This package demonstrates how to sign and verify AT Protocol lexicon records using cryptographic signatures, following the AT Protocol cryptography specifications.

update readme.md

Changed files
+101 -8
+101 -8
README.md
··· 15 15 4. Verifying the signature 16 16 5. Testing invalid signatures (hardcoded values) 17 17 18 + ## Project Structure 19 + 20 + ``` 21 + jwks/ 22 + ├── cmd/ 23 + │ ├── keys/ # Key generation utilities 24 + │ │ ├── generate_keys.go 25 + │ │ └── generate_keys_test.go 26 + │ └── verify/ # Signature verification utilities 27 + │ ├── sign_verify.go 28 + │ └── sign_verify_test.go 29 + └── README.md 30 + ``` 31 + 18 32 ## Usage 19 33 34 + ### Generating Keys 35 + 36 + To generate a new key pair: 37 + 20 38 ```bash 21 - go run sign_verify.go 39 + # From the jwks directory 40 + go run ./cmd/keys/generate_keys.go 41 + ``` 42 + 43 + This will: 44 + 1. Generate a new P-256 key pair 45 + 2. Save the keys to `keys/keypair.json` 46 + 3. Print the keys in various formats (Multibase and DID) 47 + 48 + ### Using the Signature Library 49 + 50 + The `sign_verify.go` file provides a library for signing and verifying AT Protocol lexicon records. The `LexiconRecord` struct includes a `Signature` field that is used to store the signature after signing: 51 + 52 + ```go 53 + type LexiconRecord struct { 54 + Type string `json:"$type"` 55 + Text string `json:"text"` 56 + CreatedAt string `json:"createdAt"` 57 + Author string `json:"author"` 58 + Signature string `json:"signature,omitempty"` // Used to store the signature 59 + } 60 + ``` 61 + 62 + Here's how to use it in your code: 63 + 64 + ```go 65 + import "github.com/yourusername/jwks/cmd/verify" 66 + 67 + // Create a record (Signature field will be empty initially) 68 + record := verify.LexiconRecord{ 69 + Type: "app.bsky.feed.post", 70 + Text: "Hello, AT Protocol!", 71 + CreatedAt: "2023-04-10T12:00:00Z", 72 + Author: "did:plc:example123", 73 + } 74 + 75 + // Sign the record - this will set the Signature field 76 + err := record.Sign(privateKey) 77 + if err != nil { 78 + log.Fatal(err) 79 + } 80 + // record.Signature now contains the base64-encoded signature 81 + 82 + // Verify the signature using the public key and the stored signature 83 + err = record.VerifySignature(publicKey) 84 + if err != nil { 85 + log.Fatal(err) 86 + } 22 87 ``` 23 88 24 - The script will: 25 - 1. Generate a new key pair 26 - 2. Run two test cases: 27 - - Working Record Test: Creates, signs, and verifies a valid record 28 - - Broken Record Test: Demonstrates verification failure with a hardcoded signature 89 + Important notes about the signature field: 90 + 1. The `Signature` field is optional in the JSON representation (`omitempty` tag) 91 + 2. When signing a record, the `Signature` field is automatically set with the base64-encoded signature 92 + 3. When verifying a record, the `Signature` field must be present and contain a valid signature 93 + 4. The verification process: 94 + - Extracts the signature from the `Signature` field 95 + - Creates a copy of the record with an empty signature 96 + - Verifies the signature against this unsigned copy 97 + - Uses the provided public key to verify the signature 98 + 99 + ### Running Tests 100 + 101 + To run all tests: 102 + 103 + ```bash 104 + # From the jwks directory 105 + go test ./... 106 + ``` 107 + 108 + To run tests with coverage: 109 + 110 + ```bash 111 + # From the jwks directory 112 + go test -cover ./... 113 + ``` 29 114 30 115 ## Implementation Details 31 116 ··· 38 123 39 124 ## Code Structure 40 125 41 - The example includes: 126 + ### Key Generation (`cmd/keys/`) 127 + - `KeyPair` struct for storing public/private keys 128 + - Functions for generating and saving key pairs 129 + - Tests for key generation and verification 130 + 131 + ### Signature Verification (`cmd/verify/`) 42 132 - `LexiconRecord` struct with embedded signature field 43 133 - Methods for handling signatures: 44 134 - `UnsignedBytes()`: Gets record bytes without signature 45 135 - `Sign()`: Signs the record 46 136 - `VerifySignature()`: Verifies the record's signature 47 - - Test functions demonstrating both valid and invalid signatures 137 + - Comprehensive test suite covering: 138 + - Valid signature creation and verification 139 + - Invalid signature handling 140 + - Error cases (nil keys, unsigned records, etc.) 48 141 49 142 ## References 50 143