11package main
22
33import (
4+ "bytes"
45 "context"
6+ "crypto/sha256"
57 "encoding/base64"
68 "encoding/json"
79 "flag"
@@ -157,8 +159,9 @@ func lookupKey(serverURL string, v note.Verifier, vrfKey *vrf.PublicKey, email s
157159 }
158160
159161 // Verify spicy signature
160- vrfHashB64 := base64 .StdEncoding .EncodeToString (vrfHash )
161- entry := fmt .Appendf (nil , "%s\n %s\n " , vrfHashB64 , result .Pubkey )
162+ h := sha256 .New ()
163+ h .Write ([]byte (result .Pubkey ))
164+ entry := h .Sum (vrfHash ) // vrf-r255(email) || SHA-256(pubkey)
162165 if err := torchwood .VerifyProof (v .Name (), func (b []byte ) (* note.Note , error ) {
163166 return note .Open (b , note .VerifierList (v ))
164167 }, tlog .RecordHash (entry ), []byte (result .Proof )); err != nil {
@@ -169,7 +172,7 @@ func lookupKey(serverURL string, v note.Verifier, vrfKey *vrf.PublicKey, email s
169172}
170173
171174func monitorLog (serverURL string , v note.Verifier , vrfKey * vrf.PublicKey , email string ) ([]string , error ) {
172- // Request the VRF proof from the monitor endpoint
175+ // Request the VRF proof and history from the monitor endpoint
173176 monitorURL := serverURL + "/api/monitor?email=" + url .QueryEscape (email )
174177 client := & http.Client {
175178 Timeout : 10 * time .Second ,
@@ -187,8 +190,9 @@ func monitorLog(serverURL string, v note.Verifier, vrfKey *vrf.PublicKey, email
187190 return nil , fmt .Errorf ("keyserver error: %s - %s" , resp .Status , string (body ))
188191 }
189192 var result struct {
190- Email string `json:"email"`
191- VRFProof []byte `json:"vrf_proof"`
193+ Email string `json:"email"`
194+ VRFProof []byte `json:"vrf_proof"`
195+ History []string `json:"history"`
192196 }
193197 if err := json .NewDecoder (resp .Body ).Decode (& result ); err != nil {
194198 return nil , fmt .Errorf ("failed to parse response: %w" , err )
@@ -197,6 +201,13 @@ func monitorLog(serverURL string, v note.Verifier, vrfKey *vrf.PublicKey, email
197201 return nil , fmt .Errorf ("keyserver returned unexpected email: %q" , result .Email )
198202 }
199203
204+ // Prepare map of hashes of historical keys
205+ historyHashes := make (map [[32 ]byte ]string )
206+ for _ , pk := range result .History {
207+ h := sha256 .Sum256 ([]byte (pk ))
208+ historyHashes [h ] = pk
209+ }
210+
200211 // Compute and verify VRF hash
201212 vrfProof , err := vrf .NewProof (result .VRFProof )
202213 if err != nil {
@@ -233,17 +244,17 @@ func monitorLog(serverURL string, v note.Verifier, vrfKey *vrf.PublicKey, email
233244 // Fetch all entries up to the checkpoint size
234245 var pubkeys []string
235246 for i , entry := range c .AllEntries (context .Background (), checkpoint .Tree , 0 ) {
236- e , rest , ok := strings .Cut (string (entry ), "\n " )
237- if ! ok {
238- return nil , fmt .Errorf ("malformed log entry %d: %q" , i , string (entry ))
247+ if len (entry ) != 64 + 32 {
248+ return nil , fmt .Errorf ("invalid entry size at index %d" , i )
239249 }
240- k , rest , ok := strings .Cut (rest , "\n " )
241- if ! ok || rest != "" {
242- return nil , fmt .Errorf ("malformed log entry %d: %q" , i , string (entry ))
250+ if ! bytes .Equal (entry [:64 ], vrfHash ) {
251+ continue
243252 }
244- if e == base64 .StdEncoding .EncodeToString (vrfHash ) {
245- pubkeys = append (pubkeys , k )
253+ pk , ok := historyHashes [([32 ]byte )(entry [64 :])]
254+ if ! ok {
255+ return nil , fmt .Errorf ("found unknown public key hash in log at index %d" , i )
246256 }
257+ pubkeys = append (pubkeys , pk )
247258 }
248259 if c .Err () != nil {
249260 return nil , fmt .Errorf ("error fetching log entries: %w" , c .Err ())
0 commit comments