github.com/google/trillian-examples@v0.0.0-20240520080811-0d40d35cef0e/helloworld/client.go (about) 1 // Copyright 2021 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package helloworld runs a simple client, designed to interact with a personality. 16 package helloworld 17 18 import ( 19 "context" 20 "fmt" 21 22 trillian "github.com/google/trillian" 23 "github.com/google/trillian-examples/helloworld/personality" 24 "github.com/transparency-dev/merkle" 25 "github.com/transparency-dev/merkle/proof" 26 "github.com/transparency-dev/merkle/rfc6962" 27 28 "github.com/transparency-dev/formats/log" 29 "golang.org/x/mod/sumdb/note" 30 ) 31 32 // Personality is the front-end for the Trillian log. 33 type Personality interface { 34 // Append stores an entry in the log and, once it is there, returns a 35 // new checkpoint that commits to the new entry (in addition to all 36 // previous ones). 37 Append(ctx context.Context, entry []byte) (personality.SignedCheckpoint, error) 38 39 // ProveIncl proves the inclusion of a given entry in a given checkpoint size. 40 // It is the job of the client to verify this inclusion proof in order to convince 41 // itself that the entry really has been included in the log. 42 ProveIncl(ctx context.Context, cpSize uint64, entry []byte) (*trillian.Proof, error) 43 44 // UpdateChkpt provides a new checkpoint along with a consistency proof to it 45 // from the specified older checkpoint size. 46 // Again, it is the job of the client to verify this consistency proof. 47 UpdateChkpt(ctx context.Context, oldCPSize uint64) (personality.SignedCheckpoint, *trillian.Proof, error) 48 } 49 50 // Client is a verifier that maintains a checkpoint as state. 51 type Client struct { 52 h merkle.LogHasher 53 chkpt *log.Checkpoint 54 person Personality 55 sigVerifier note.Verifier 56 } 57 58 // NewClient creates a new client with an empty checkpoint and a given 59 // personality to talk to. In real usage, a client should persist this 60 // checkpoint across different runs to ensure consistency. 61 func NewClient(prsn Personality, nv note.Verifier) Client { 62 return Client{ 63 person: prsn, 64 h: rfc6962.DefaultHasher, 65 sigVerifier: nv, 66 } 67 } 68 69 // VerIncl allows the client to check inclusion of a given entry. 70 func (c Client) VerIncl(entry []byte, pf *trillian.Proof) bool { 71 leafHash := rfc6962.DefaultHasher.HashLeaf(entry) 72 if err := proof.VerifyInclusion(c.h, uint64(pf.LeafIndex), c.chkpt.Size, leafHash, pf.Hashes, c.chkpt.Hash); err != nil { 73 return false 74 } 75 return true 76 } 77 78 // UpdateChkpt allows a client to update its stored checkpoint. In a real use 79 // case it would be important for the client to check the signature contained 80 // in the checkpoint before verifying consistency. 81 func (c *Client) UpdateChkpt(chkptNewRaw personality.SignedCheckpoint, pf *trillian.Proof) error { 82 chkptNew, _, _, err := log.ParseCheckpoint(chkptNewRaw, "Hello World Log", c.sigVerifier) 83 if err != nil { 84 return fmt.Errorf("failed to verify checkpoint: %w", err) 85 } 86 // If there is no checkpoint then just use this one no matter what. 87 if c.chkpt.Size != 0 { 88 // Else make sure this new checkpoint is consistent with the current one. 89 hashes := pf.GetHashes() 90 if err := proof.VerifyConsistency(c.h, c.chkpt.Size, chkptNew.Size, hashes, c.chkpt.Hash, chkptNew.Hash); err != nil { 91 return fmt.Errorf("failed to verify consistency proof: %w", err) 92 } 93 } 94 // If all is good then set this as the new checkpoint. 95 c.chkpt = chkptNew 96 return nil 97 }