-
Notifications
You must be signed in to change notification settings - Fork 337
/
proofs.go
107 lines (86 loc) · 3.01 KB
/
proofs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
Copyright 2019-2020 vChain, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package schema
import (
"bytes"
"crypto/sha256"
"github.com/codenotary/merkletree"
)
// Verify returns true iff the _InclusionProof_ proves that _leaf_ is included into _i.Root_'s history at
// the given _index_.
// todo(leogr): can we use schema.Item instead of (index,leaf)?
func (i *InclusionProof) Verify(index uint64, leaf []byte) bool {
if i == nil || i.Index != index || bytes.Compare(leaf, i.Leaf) != 0 {
return false
}
var path merkletree.Path
path.FromSlice(i.Path)
var rt, lf [sha256.Size]byte
copy(rt[:], i.Root)
copy(lf[:], i.Leaf)
return path.VerifyInclusion(i.At, i.Index, rt, lf)
}
// Verify returns true iff the _ConsistencyProof_ proves that _c.SecondRoot_'s history is including the history of
// the provided _prevRoot_ up to the position _c.First_.
func (c *ConsistencyProof) Verify(prevRoot Root) bool {
if c == nil || c.First != prevRoot.GetIndex() {
return false
}
var path merkletree.Path
path.FromSlice(c.Path)
var firstRoot, secondRoot [sha256.Size]byte
copy(firstRoot[:], prevRoot.GetRoot())
copy(secondRoot[:], c.SecondRoot)
if path.VerifyConsistency(c.Second, c.First, secondRoot, firstRoot) {
c.FirstRoot = prevRoot.GetRoot()
return true
}
return false
}
// Verify returns true iff the _Proof_ proves that the given _leaf_ is included into _p.Root_'s history at position _p.Index_
// and that the provided _prevRoot_ is included into _p.Root_'s history.
// Providing a zerovalue for _prevRoot_ signals that no previous root is available, thus consistency proof will be skipped.
func (p *Proof) Verify(leaf []byte, prevRoot Root) bool {
if p == nil || bytes.Compare(leaf, p.Leaf) != 0 {
return false
}
var path merkletree.Path
path.FromSlice(p.InclusionPath)
var rt, lf [sha256.Size]byte
copy(rt[:], p.Root)
copy(lf[:], p.Leaf)
if !path.VerifyInclusion(p.At, p.Index, rt, lf) {
return false
}
// we cannot check consistency when the previous root is not provided
if prevRoot.GetIndex() == 0 && len(prevRoot.GetRoot()) == 0 {
return true
}
path.FromSlice(p.ConsistencyPath)
var firstRoot, secondRoot [sha256.Size]byte
copy(firstRoot[:], prevRoot.GetRoot())
copy(secondRoot[:], p.Root)
return path.VerifyConsistency(p.At, prevRoot.GetIndex(), secondRoot, firstRoot)
}
// NewRoot returns a new _Root_ object which holds values referenced by the proof _p_.
func (p *Proof) NewRoot() *Root {
if p != nil {
return &Root{
Payload: &RootIndex{
Root: append([]byte{}, p.Root...),
Index: p.At,
},
}
}
return nil
}