Skip to content

Conversation

@AmaseCocoa
Copy link
Member

RFC9421準拠の署名実装を追加します。

Add RFC9421 compliant signature implementation.

これは#12 を解決します

@AmaseCocoa AmaseCocoa self-assigned this Jun 20, 2025
@AmaseCocoa AmaseCocoa added the enhancement New feature or request label Jun 20, 2025
@github-actions
Copy link

Lint Result

Not fixable checks
src/apsig/rfc9421.py:6:42: F401 [*] `cryptography.hazmat.backends.default_backend` imported but unused
  |
4 | from pprint import pprint
5 |
6 | from cryptography.hazmat.backends import default_backend
  |                                          ^^^^^^^^^^^^^^^ F401
7 | from cryptography.hazmat.primitives.asymmetric import ed25519
8 | from cryptography.hazmat.primitives import serialization
  |
  = help: Remove unused import: `cryptography.hazmat.backends.default_backend`

src/apsig/rfc9421.py:8:44: F401 [*] `cryptography.hazmat.primitives.serialization` imported but unused
   |
 6 | from cryptography.hazmat.backends import default_backend
 7 | from cryptography.hazmat.primitives.asymmetric import ed25519
 8 | from cryptography.hazmat.primitives import serialization
   |                                            ^^^^^^^^^^^^^ F401
 9 |
10 | from apsig.draft.tools import calculate_digest
   |
   = help: Remove unused import: `cryptography.hazmat.primitives.serialization`

Found 2 errors.
[*] 2 fixable with the `--fix` option.

@AmaseCocoa AmaseCocoa linked an issue Jun 20, 2025 that may be closed by this pull request
@github-actions
Copy link

Lint Result

Not fixable checks
src/apsig/rfc9421.py:6:42: F401 [*] `cryptography.hazmat.backends.default_backend` imported but unused
  |
4 | from pprint import pprint
5 |
6 | from cryptography.hazmat.backends import default_backend
  |                                          ^^^^^^^^^^^^^^^ F401
7 | from cryptography.hazmat.primitives.asymmetric import ed25519
8 | from cryptography.hazmat.primitives import serialization
  |
  = help: Remove unused import: `cryptography.hazmat.backends.default_backend`

src/apsig/rfc9421.py:8:44: F401 [*] `cryptography.hazmat.primitives.serialization` imported but unused
   |
 6 | from cryptography.hazmat.backends import default_backend
 7 | from cryptography.hazmat.primitives.asymmetric import ed25519
 8 | from cryptography.hazmat.primitives import serialization
   |                                            ^^^^^^^^^^^^^ F401
 9 |
10 | from apsig.draft.tools import calculate_digest
   |
   = help: Remove unused import: `cryptography.hazmat.primitives.serialization`

Found 2 errors.
[*] 2 fixable with the `--fix` option.

@AmaseCocoa
Copy link
Member Author

AmaseCocoa commented Jul 31, 2025

Todo

  • Fedifyで何故かActorから鍵が読み込まれない
    • 生成部分は8b32のテストサーバーと共通なのでRFCの実装側に問題がある可能性あり
  • 署名の検証

@github-actions
Copy link

Lint Result

Not fixable checks
src/apsig/rfc9421.py:6:42: F401 [*] `cryptography.hazmat.backends.default_backend` imported but unused
  |
4 | from pprint import pprint
5 |
6 | from cryptography.hazmat.backends import default_backend
  |                                          ^^^^^^^^^^^^^^^ F401
7 | from cryptography.hazmat.primitives.asymmetric import ed25519
8 | from cryptography.hazmat.primitives import serialization
  |
  = help: Remove unused import: `cryptography.hazmat.backends.default_backend`

src/apsig/rfc9421.py:8:44: F401 [*] `cryptography.hazmat.primitives.serialization` imported but unused
   |
 6 | from cryptography.hazmat.backends import default_backend
 7 | from cryptography.hazmat.primitives.asymmetric import ed25519
 8 | from cryptography.hazmat.primitives import serialization
   |                                            ^^^^^^^^^^^^^ F401
 9 |
10 | from apsig.draft.tools import calculate_digest
   |
   = help: Remove unused import: `cryptography.hazmat.primitives.serialization`

Found 2 errors.
[*] 2 fixable with the `--fix` option.

@github-actions
Copy link

Lint Result

Not fixable checks
F401 [*] `pyfill.datetime.utcnow` imported but unused
  --> src/apsig/rfc9421.py:17:29
   |
15 | )
16 | from multiformats import multibase, multicodec
17 | from pyfill.datetime import utcnow
   |                             ^^^^^^
18 |
19 | from apsig.draft.tools import calculate_digest
   |
help: Remove unused import: `pyfill.datetime.utcnow`

F841 Local variable `gmt_time` is assigned to but never used
   --> src/apsig/rfc9421.py:197:9
    |
195 |             raise ValueError("Unknown created value")
196 |         gmt_tz = pytz.timezone("GMT")
197 |         gmt_time = gmt_tz.localize(created_timestamp)
    |         ^^^^^^^^
198 |         request_time = created_timestamp.astimezone(pytz.utc)
199 |         current_time = dt.datetime.now(dt.UTC)
    |
help: Remove assignment to unused variable `gmt_time`

Found 2 errors.
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
F841 Local variable `gmt_tz` is assigned to but never used
   --> src/apsig/rfc9421.py:194:9
    |
192 |         else:
193 |             raise ValueError("Unknown created value")
194 |         gmt_tz = pytz.timezone("GMT")
    |         ^^^^^^
195 |         request_time = created_timestamp.astimezone(pytz.utc)
196 |         current_time = dt.datetime.now(dt.UTC)
    |
help: Remove assignment to unused variable `gmt_tz`

Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
All checks passed!

@AmaseCocoa AmaseCocoa mentioned this pull request Oct 21, 2025
8 tasks
  This commit overhauls the project's development and build tooling by
  migrating from PDM to uv and Hatch.

  Key changes include:
   - PDM is replaced with uv for dependency management.
   - Hatch is now the build backend, using setuptools-scm for
     versioning.
   - Ruff and Pyrefly are added for linting and static analysis.
   - The minimum required Python version is lowered to 3.10.
   - Zed editor settings are added for the new language servers.

  This also fixes an issue in RFC9421 processing by adding the 'alg'
  parameter to signatures and properly stripping header whitespace.

  BREAKING CHANGE: The project no longer uses PDM. Developers must now
  use uv to install and manage dependencies.
@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W293 [*] Blank line contains whitespace
  --> src/apsig/ld_signature.py:72:1
   |
70 |         else:
71 |             created_str = created.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
72 |         
   | ^^^^^^^^
73 |         default_options: dict[str, str | datetime.datetime] = {
74 |             "@context": "https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld",  # "https://w3id.org/identity/v1"
   |
help: Remove whitespace from blank line

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 9 errors.
[*] 2 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W293 [*] Blank line contains whitespace
  --> src/apsig/ld_signature.py:72:1
   |
70 |         else:
71 |             created_str = created.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
72 |         
   | ^^^^^^^^
73 |         default_options: dict[str, str | datetime.datetime] = {
74 |             "@context": "https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld",  # "https://w3id.org/identity/v1"
   |
help: Remove whitespace from blank line

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 9 errors.
[*] 2 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W293 [*] Blank line contains whitespace
  --> src/apsig/ld_signature.py:72:1
   |
70 |         else:
71 |             created_str = created.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
72 |         
   | ^^^^^^^^
73 |         default_options: dict[str, str | datetime.datetime] = {
74 |             "@context": "https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld",  # "https://w3id.org/identity/v1"
   |
help: Remove whitespace from blank line

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 9 errors.
[*] 2 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W293 [*] Blank line contains whitespace
  --> src/apsig/ld_signature.py:72:1
   |
70 |         else:
71 |             created_str = created.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
72 |         
   | ^^^^^^^^
73 |         default_options: dict[str, str | datetime.datetime] = {
74 |             "@context": "https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld",  # "https://w3id.org/identity/v1"
   |
help: Remove whitespace from blank line

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 9 errors.
[*] 2 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W293 [*] Blank line contains whitespace
  --> src/apsig/ld_signature.py:72:1
   |
70 |         else:
71 |             created_str = created.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
72 |         
   | ^^^^^^^^
73 |         default_options: dict[str, str | datetime.datetime] = {
74 |             "@context": "https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld",  # "https://w3id.org/identity/v1"
   |
help: Remove whitespace from blank line

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 9 errors.
[*] 2 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W293 [*] Blank line contains whitespace
  --> src/apsig/ld_signature.py:72:1
   |
70 |         else:
71 |             created_str = created.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
72 |         
   | ^^^^^^^^
73 |         default_options: dict[str, str | datetime.datetime] = {
74 |             "@context": "https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld",  # "https://w3id.org/identity/v1"
   |
help: Remove whitespace from blank line

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 9 errors.
[*] 2 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@codecov
Copy link

codecov bot commented Dec 28, 2025

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 8 errors.
[*] 1 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 8 errors.
[*] 1 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@github-actions
Copy link

Lint Result

Not fixable checks
N801 Class name `draftSigner` should use CapWords convention
  --> src/apsig/draft/sign.py:14:7
   |
14 | class draftSigner:
   |       ^^^^^^^^^^^
15 |     @staticmethod
16 |     @deprecated(
   |

N801 Class name `draftVerifier` should use CapWords convention
  --> src/apsig/draft/verify.py:18:7
   |
18 | class draftVerifier:
   |       ^^^^^^^^^^^^^
19 |     @staticmethod
20 |     @deprecated(
   |

N818 Exception name `MissingSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:4:7
  |
2 |     pass
3 |
4 | class MissingSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
5 |     pass
  |

N818 Exception name `UnknownSignature` should be named with an Error suffix
 --> src/apsig/exceptions.py:7:7
  |
5 |     pass
6 |
7 | class UnknownSignature(SignatureError):
  |       ^^^^^^^^^^^^^^^^
8 |     pass
  |

N818 Exception name `VerificationFailed` should be named with an Error suffix
  --> src/apsig/exceptions.py:10:7
   |
 8 |     pass
 9 |
10 | class VerificationFailed(SignatureError):
   |       ^^^^^^^^^^^^^^^^^^
11 |     pass
   |

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:10:73
   |
 8 | class ProofSigner:
 9 |     """
10 |     A class for signing documents using the Ed25519 signature algorithm, 
   |                                                                         ^
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
   |
help: Remove trailing whitespace

W291 Trailing whitespace
  --> src/apsig/proof/sign.py:13:61
   |
11 |     implementing Object Integrity Proofs as specified in FEP-8b32.
12 |
13 |     This class provides methods to generate keys, sign data, 
   |                                                             ^
14 |     canonicalize documents, and create integrity proofs.
   |
help: Remove trailing whitespace

W293 [*] Blank line contains whitespace
  --> src/apsig/proof/sign.py:84:1
   |
82 |         proof["proofValue"] = multibase.encode(proof_bytes, "base58btc")
83 |         return proof
84 |     
   | ^^^^
85 |     def sign(self, unsecured_document: dict, options: dict):
86 |         """Signs the unsecured document by creating a proof and returning the signed document.
   |
help: Remove whitespace from blank line

Found 8 errors.
[*] 1 fixable with the `--fix` option (2 hidden fixes can be enabled with the `--unsafe-fixes` option).

@AmaseCocoa AmaseCocoa marked this pull request as ready for review December 28, 2025 20:47
@AmaseCocoa
Copy link
Member Author

/gemini summary

@AmaseCocoa
Copy link
Member Author

/gemini review

@gemini-code-assist
Copy link

Summary of Changes

This pull request significantly expands the library's cryptographic capabilities by integrating RFC9421 compliant HTTP message signatures, enabling robust signing and verification of web requests. Concurrently, it modernizes the development workflow through a comprehensive migration to pytest for testing and the adoption of advanced linting and formatting tools. These changes, coupled with dependency updates and codebase cleanup, aim to enhance security, improve developer efficiency, and ensure compatibility with newer Python versions.

Highlights

  • New RFC9421 HTTP Message Signatures: Introduced RFC9421Signer and RFC9421Verifier classes in a new module src/apsig/rfc9421.py to support RFC9421 compliant HTTP message signing and verification.
  • Testing Framework Migration: Migrated unit tests from unittest to pytest across several test files, including test_draft.py, test_ld.py, test_multibase_ed25519.py, and test_proof.py, and updated Taskfile.yaml accordingly.
  • Development Tooling Enhancements: Added Zed editor settings (.zed/settings.json) and comprehensive ruff and pyrefly configurations in pyproject.toml to improve linting, formatting, and overall developer experience.
  • Dependency and Python Version Updates: Added http-sf and authlib dependencies, removed pyfill, dropped support for Python 3.9, and added support for Python 3.14 in pyproject.toml.
  • Codebase Cleanup: Removed several end-to-end test server files (dev/e2e/faker/actor.py, dev/e2e/server_ld.py, dev/e2e/server_proof.py) and a datetime polyfill (src/apsig/__polyfill/datetime.py), streamlining the project structure.
Changelog
  • .zed/settings.json
    • Added Zed editor configuration for Python language servers (ruff, pyrefly) to enhance code editing and analysis.
  • Taskfile.yaml
    • Updated the test command to utilize pytest for running tests, replacing the previous unittest command.
  • dev/e2e/faker/actor.py
    • Removed, streamlining the end-to-end testing setup.
  • dev/e2e/server_ld.py
    • Removed, streamlining the end-to-end testing setup.
  • dev/e2e/server_proof.py
    • Removed, streamlining the end-to-end testing setup.
  • pyproject.toml
    • Added http-sf and authlib to the project dependencies.
    • Removed pyfill from dependencies.
    • Updated Python classifiers to remove 3.9 and include 3.14.
    • Introduced detailed ruff and pyrefly configurations for code quality enforcement.
    • Refactored [dependency-groups] to categorize development dependencies.
    • Removed the [tool.pdm.version] section.
  • src/apsig/__polyfill/datetime.py
    • Removed, as direct datetime.datetime.now(datetime.timezone.utc) usage is now preferred.
  • src/apsig/_version.py
    • Version string updated to 0.5.4.post1.dev34+g449058cc7.d20251228.
  • src/apsig/draft/sign.py
    • Applied minor code style and type hinting improvements.
  • src/apsig/draft/verify.py
    • Applied minor code style and type hinting improvements, and updated datetime usage for consistency.
  • src/apsig/ld_signature.py
    • Made minor code style and type hinting adjustments, removed utcnow import, and added a type check for jsonld.normalize output.
  • src/apsig/proof/verify.py
    • Applied minor code style and type hinting improvements.
  • src/apsig/rfc9421.py
    • Added a new file containing RFC9421Signer and RFC9421Verifier classes for HTTP message signature implementation.
  • src/apsig/tools.py
    • Applied minor code style adjustments.
  • tests/test_draft.py
    • Converted from unittest to pytest framework, utilizing fixtures.
  • tests/test_ld.py
    • Converted from unittest to pytest framework, utilizing fixtures.
  • tests/test_multibase_ed25519.py
    • Converted from unittest to pytest framework, utilizing fixtures.
  • tests/test_proof.py
    • Converted from unittest to pytest framework, utilizing fixtures.
  • tests/test_rfc9421.py
    • Added new test file specifically for the RFC9421 implementation.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/test.yml
Activity
  • Linting reports from github-actions[bot] consistently highlighted issues such as unused imports (F401), incorrect class naming conventions (N801), missing exception suffixes (N818), and trailing whitespace (W291, W293).
  • The author, AmaseCocoa, noted a "Todo" item, indicating an ongoing task to investigate why keys are not being loaded from Actor in Fedify, suggesting a potential issue with the RFC implementation, and also mentioned "署名の検証" (signature verification) as a task.
  • Codecov bot initiated coverage reporting for the pull request.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

このプルリクエストは、RFC9421準拠の署名実装を追加するもので、素晴らしい機能追加です。また、テストをunittestからpytestに移行し、依存関係やコードフォーマットを整理することで、プロジェクトの保守性も向上しています。新しいRFC9421の実装は、複数のアルゴリズムをサポートしており包括的です。レビューを通して、新しい実装にデッドコード、パラメータ処理のバグ、署名抽出ロジックの分かりにくさなど、いくつかの改善点を見つけました。これらの点を修正することで、実装がより堅牢になるでしょう。

@AmaseCocoa AmaseCocoa merged commit 875e765 into main Dec 28, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implementing RFC 9421

2 participants