+101
-8
README.md
+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