Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add verification methods #74

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5a6ef4c
Add verification method for DirectoryProof
vqhuy Sep 22, 2016
9c1b72c
[WIP] Client struct in protocol package
vqhuy Oct 12, 2016
1935b5d
[WIP] Verify temporary bindings from client side
vqhuy Oct 12, 2016
3ddad77
Verify temporary bindings from client side
vqhuy Oct 13, 2016
20a99bb
s/ErrorBreakPromise/ErrorBrokenPromise
vqhuy Oct 14, 2016
83d661c
Verify TB based on the current STR
vqhuy Oct 14, 2016
7f59771
Add doc for Verify method
vqhuy Oct 17, 2016
b0e934c
Better naming & proof type check should be included in ConsistencyChecks
vqhuy Oct 21, 2016
24514c8
Fix cc.verifyProofTypeWithTB
vqhuy Oct 21, 2016
5217637
Fix TB's verification
vqhuy Oct 24, 2016
b4c0427
Add todo note for missed epoch verifications
vqhuy Oct 25, 2016
4896c04
Use canonical TODO
vqhuy Oct 27, 2016
98769da
Makes the verifying flow clearer
vqhuy Oct 31, 2016
6cd4985
Remove tests with regard to #111
vqhuy Oct 31, 2016
a6c3bf2
Remove unused constant
vqhuy Oct 31, 2016
8ac625d
Separate TB's verifications
vqhuy Nov 1, 2016
4af67ae
Separate verifications of each request type:
vqhuy Nov 3, 2016
e91c017
Refine verification logic
vqhuy Nov 4, 2016
0fd9641
Fix verifyFulfilledPromise
vqhuy Nov 5, 2016
2e3c340
verifyAuthPath and verifySTR should not depend on the current state s…
vqhuy Nov 5, 2016
d8342b6
Refactor tests
vqhuy Nov 5, 2016
cbfda66
Fix comments (thanks to @liamsi and @arlolra)
vqhuy Nov 10, 2016
78aee54
Abstract proof type away from the return value.
vqhuy Nov 11, 2016
c023d7d
Rebase master
vqhuy Nov 11, 2016
6491633
Split STR verification.
vqhuy Nov 11, 2016
41cc371
Make some of the failure cases (proofType, error, reqType combination…
vqhuy Nov 12, 2016
80e453c
Separate updating str from checking consistency
arlolra Nov 12, 2016
4a345e8
Separate updating tbs from checking consistency
arlolra Nov 12, 2016
8e97d88
savedSTR should not be nil when initialization
vqhuy Nov 14, 2016
e5d36a7
Remove unused errors
vqhuy Nov 14, 2016
a2e2a48
Consolidate hash chain verification
vqhuy Nov 14, 2016
31c5b35
Refactor checks
vqhuy Nov 14, 2016
25a356b
Fix fulfilled TB verification.
vqhuy Nov 14, 2016
fec6cff
Add comment for HandleResponse
vqhuy Nov 14, 2016
ea46aaa
Re-organize code
vqhuy Nov 15, 2016
09784a6
Revert 25a356b0c3e3e74b31989965740c8a6a653d5fca
vqhuy Nov 15, 2016
d2ed2c9
tb.Verify() instead (credit to @Liamsi)
vqhuy Nov 15, 2016
33e5f74
Revert 8e97d880c55c91618ef5e64a8f7527b335ad29ce
vqhuy Nov 15, 2016
d7581cc
Fix 31c5b35ba92a378441da8c49aaf73396e03d175b
vqhuy Nov 15, 2016
16949b2
Refactor
vqhuy Nov 15, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion keyserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func TestUpdateDirectory(t *testing.T) {
timer := time.NewTimer(1 * time.Second)
<-timer.C
str1 := server.dir.LatestSTR()
if str0.Epoch != 0 || str1.Epoch != 1 || !str1.VerifyHashChain(str0.Signature) {
if str0.Epoch != 0 || str1.Epoch != 1 || !str1.VerifyHashChain(str0) {
t.Fatal("Expect next STR in hash chain")
}
})
Expand Down
37 changes: 33 additions & 4 deletions merkletree/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,21 @@ func (n *ProofNode) hash(treeNonce []byte) []byte {
}
}

type ProofType int

const (
undeterminedProof ProofType = iota
Copy link
Member

Choose a reason for hiding this comment

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

Is undeterminedProof still relevant? Doesn't seem like it's being used.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Ok, sorry, I missed that.

ProofOfAbsence
ProofOfInclusion
)

type AuthenticationPath struct {
TreeNonce []byte
PrunedTree [][crypto.HashSizeByte]byte
LookupIndex []byte
VrfProof []byte
Leaf *ProofNode
proofType ProofType
}

func (ap *AuthenticationPath) authPathHash() []byte {
Expand All @@ -59,11 +68,14 @@ func (ap *AuthenticationPath) authPathHash() []byte {
return hash
}

func (ap *AuthenticationPath) verifyBinding(key, value []byte) bool {
return bytes.Equal(ap.Leaf.Value, value) &&
ap.Leaf.Commitment.Verify(key, value)
}

// Verify should be called after the vrf index is verified successfully
func (ap *AuthenticationPath) Verify(treeHash []byte) bool {
// step 1. Verify if it's a proof of inclusion/proof of absence
if !bytes.Equal(ap.Leaf.Index, ap.LookupIndex) {
// proof of absence
func (ap *AuthenticationPath) Verify(key, value, treeHash []byte) bool {
if ap.ProofType() == ProofOfAbsence { // proof of absence
// Check if i and j match in the first l bits
indexBits := util.ToBits(ap.Leaf.Index)
lookupIndexBits := util.ToBits(ap.LookupIndex)
Expand All @@ -72,10 +84,27 @@ func (ap *AuthenticationPath) Verify(treeHash []byte) bool {
return false
}
}
} else { // proof of inclusion
// Verify the key-value binding returned in the ProofNode
if !ap.verifyBinding(key, value) {
return false
}
}

// step 2. Verify the auth path of the returned leaf
if !bytes.Equal(treeHash, ap.authPathHash()) {
return false
}
return true
}

func (ap *AuthenticationPath) ProofType() ProofType {
if ap.proofType == undeterminedProof {
if bytes.Equal(ap.LookupIndex, ap.Leaf.Index) {
ap.proofType = ProofOfInclusion
} else {
ap.proofType = ProofOfAbsence
}
}
return ap.proofType
}
25 changes: 8 additions & 17 deletions merkletree/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,14 @@ func TestVerifyProof(t *testing.T) {
if proof.Leaf.Value == nil {
t.Fatal("Expect returned leaf's value is not nil")
}
// step 1. ensure this is a proof of inclusion by comparing the returned indices
// ensure this is a proof of inclusion by comparing the returned indices
// and verifying the VRF index as well.
if !bytes.Equal(proof.LookupIndex, proof.Leaf.Index) ||
!bytes.Equal(vrfPrivKey1.Compute([]byte(key3)), proof.LookupIndex) {
t.Fatal("Expect a proof of inclusion")
}
// step 2. verify commitment
if !proof.Leaf.Commitment.Verify([]byte(key3), proof.Leaf.Value) {
t.Fatal("Commitment verification returns false")
}
// step 3. verify auth path
if !proof.Verify(m.hash) {
// verify auth path
if !proof.Verify([]byte(key3), val3, m.hash) {
t.Error("Proof of inclusion verification failed.")
}

Expand All @@ -82,7 +78,7 @@ func TestVerifyProof(t *testing.T) {
!bytes.Equal(vrfPrivKey1.Compute([]byte("123")), proof.LookupIndex) {
t.Fatal("Expect a proof of absence")
}
if !proof.Verify(m.hash) {
if !proof.Verify([]byte("123"), nil, m.hash) {
t.Error("Proof of absence verification failed.")
}
}
Expand Down Expand Up @@ -115,7 +111,7 @@ func TestVerifyProofSamePrefix(t *testing.T) {
util.ToBytes(util.ToBits(absentIndex)[:proof.Leaf.Level])) {
t.Fatal("Expect these indices share the same prefix in the first bit")
}
if !proof.Verify(m.hash) {
if !proof.Verify([]byte("a"), nil, m.hash) {
t.Error("Proof of absence verification failed.")
}

Expand All @@ -125,19 +121,14 @@ func TestVerifyProofSamePrefix(t *testing.T) {
if proof.Leaf.Value == nil {
t.Fatal("Expect returned leaf's value is not nil")
}
// step 1. ensure this is a proof of inclusion by comparing the returned indices
// ensure this is a proof of inclusion by comparing the returned indices
// and verifying the VRF index as well.
if !bytes.Equal(proof.LookupIndex, proof.Leaf.Index) ||
!bytes.Equal(vrfPrivKey1.Compute([]byte(key1)), proof.LookupIndex) {
t.Fatal("Expect a proof of inclusion")
}
// step 2. verify commitment
if !proof.Leaf.Commitment.Verify([]byte(key1), proof.Leaf.Value) {
t.Fatal("Commitment verification returns false",
"got commitment salt", proof.Leaf.Commitment.Salt)
}
// step 3. verify auth path
if !proof.Verify(m.hash) {
// step 2. verify auth path
if !proof.Verify([]byte(key1), val1, m.hash) {
t.Error("Proof of inclusion verification failed.")
}
}
6 changes: 3 additions & 3 deletions merkletree/str.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (str *SignedTreeRoot) Serialize() []byte {
return strBytes
}

func (str *SignedTreeRoot) VerifyHashChain(savedSTRSig []byte) bool {
hash := crypto.Digest(savedSTRSig)
return bytes.Equal(hash, str.PreviousSTRHash)
func (str *SignedTreeRoot) VerifyHashChain(savedSTR *SignedTreeRoot) bool {
hash := crypto.Digest(savedSTR.Signature)
return str.Epoch == savedSTR.Epoch+1 && bytes.Equal(hash, str.PreviousSTRHash)
}
5 changes: 2 additions & 3 deletions merkletree/str_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import "testing"

func TestVerifyHashChain(t *testing.T) {
var N uint64 = 100
var savedSTR []byte

keyPrefix := "key"
valuePrefix := []byte("value")
Expand All @@ -13,7 +12,7 @@ func TestVerifyHashChain(t *testing.T) {
t.Fatal(err)
}

savedSTR = pad.LatestSTR().Signature
savedSTR := pad.LatestSTR()

pk, ok := pad.signKey.Public()
if !ok {
Expand All @@ -38,6 +37,6 @@ func TestVerifyHashChain(t *testing.T) {
if !str.VerifyHashChain(savedSTR) {
t.Fatal("Spurious STR at epoch", i)
}
savedSTR = str.Signature
savedSTR = str
}
}
Loading