@@ -122,38 +122,32 @@ func (proof MerkleProof) VerifyNonMembership(specs []*ics23.ProofSpec, root expo
122
122
return errorsmod .Wrapf (ErrInvalidProof , "path %v is not of type MerkleProof" , path )
123
123
}
124
124
if len (mpath .KeyPath ) != len (specs ) {
125
- return errorsmod .Wrapf (ErrInvalidProof , "path length %d not same as proof %d" ,
126
- len (mpath .KeyPath ), len (specs ))
125
+ return errorsmod .Wrapf (ErrInvalidProof , "path length %d not same as proof %d" , len (mpath .KeyPath ), len (specs ))
127
126
}
128
127
129
- switch proof .Proofs [0 ].Proof .(type ) {
130
- case * ics23.CommitmentProof_Nonexist :
131
- // VerifyNonMembership will verify the absence of key in lowest subtree, and then chain inclusion proofs
132
- // of all subroots up to final root
133
- subroot , err := proof .Proofs [0 ].Calculate ()
134
- if err != nil {
135
- return errorsmod .Wrapf (ErrInvalidProof , "could not calculate root for proof index 0, merkle tree is likely empty. %v" , err )
136
- }
137
- key , err := mpath .GetKey (uint64 (len (mpath .KeyPath ) - 1 ))
138
- if err != nil {
139
- return errorsmod .Wrapf (ErrInvalidProof , "could not retrieve key bytes for key: %s" , mpath .KeyPath [len (mpath .KeyPath )- 1 ])
140
- }
141
- if ok := ics23 .VerifyNonMembership (specs [0 ], subroot , proof .Proofs [0 ], key ); ! ok {
142
- return errorsmod .Wrapf (ErrInvalidProof , "could not verify absence of key %s. Please ensure that the path is correct." , string (key ))
143
- }
128
+ // VerifyNonMembership will verify the absence of key in lowest subtree, and then chain inclusion proofs
129
+ // of all subroots up to final root
130
+ subroot , err := proof .Proofs [0 ].Calculate ()
131
+ if err != nil {
132
+ return errorsmod .Wrapf (ErrInvalidProof , "could not calculate root for proof index 0, merkle tree is likely empty. %v" , err )
133
+ }
144
134
145
- // Verify chained membership proof starting from index 1 with value = subroot
146
- if err := verifyChainedMembershipProof (root .GetHash (), specs , proof .Proofs , mpath , subroot , 1 ); err != nil {
147
- return err
148
- }
149
- case * ics23.CommitmentProof_Exist :
150
- return errorsmod .Wrapf (ErrInvalidProof ,
151
- "got ExistenceProof in VerifyNonMembership. If this is unexpected, please ensure that proof was queried with the correct key." )
152
- default :
153
- return errorsmod .Wrapf (ErrInvalidProof ,
154
- "expected proof type: %T, got: %T" , & ics23.CommitmentProof_Nonexist {}, proof .Proofs [0 ].Proof )
135
+ key , err := mpath .GetKey (uint64 (len (mpath .KeyPath ) - 1 ))
136
+ if err != nil {
137
+ return errorsmod .Wrapf (ErrInvalidProof , "could not retrieve key bytes for key: %s" , mpath .KeyPath [len (mpath .KeyPath )- 1 ])
155
138
}
156
- return nil
139
+
140
+ np := proof .Proofs [0 ].GetNonexist ()
141
+ if np == nil {
142
+ return errorsmod .Wrapf (ErrInvalidProof , "commitment proof must be non-existence proof for verifying non-membership. got: %T" , proof .Proofs [0 ])
143
+ }
144
+
145
+ if err := np .Verify (specs [0 ], subroot , key ); err != nil {
146
+ return errorsmod .Wrapf (ErrInvalidProof , "failed to verify non-membership proof with key %s: %v" , string (key ), err )
147
+ }
148
+
149
+ // Verify chained membership proof starting from index 1 with value = subroot
150
+ return verifyChainedMembershipProof (root .GetHash (), specs , proof .Proofs , mpath , subroot , 1 )
157
151
}
158
152
159
153
// verifyChainedMembershipProof takes a list of proofs and specs and verifies each proof sequentially ensuring that the value is committed to
@@ -171,42 +165,36 @@ func verifyChainedMembershipProof(root []byte, specs []*ics23.ProofSpec, proofs
171
165
// In this case, there may be no intermediate proofs to verify and we just check that lowest proof root equals final root
172
166
subroot = value
173
167
for i := index ; i < len (proofs ); i ++ {
174
- switch proofs [i ].Proof .(type ) {
175
- case * ics23.CommitmentProof_Exist :
176
- subroot , err = proofs [i ].Calculate ()
177
- if err != nil {
178
- return errorsmod .Wrapf (ErrInvalidProof , "could not calculate proof root at index %d, merkle tree may be empty. %v" , i , err )
179
- }
180
- // Since keys are passed in from highest to lowest, we must grab their indices in reverse order
181
- // from the proofs and specs which are lowest to highest
182
- key , err := keys .GetKey (uint64 (len (keys .KeyPath ) - 1 - i ))
183
- if err != nil {
184
- return errorsmod .Wrapf (ErrInvalidProof , "could not retrieve key bytes for key %s: %v" , keys .KeyPath [len (keys .KeyPath )- 1 - i ], err )
185
- }
186
-
187
- // verify membership of the proof at this index with appropriate key and value
188
- if ok := ics23 .VerifyMembership (specs [i ], subroot , proofs [i ], key , value ); ! ok {
189
- return errorsmod .Wrapf (ErrInvalidProof ,
190
- "chained membership proof failed to verify membership of value: %X in subroot %X at index %d. Please ensure the path and value are both correct." ,
191
- value , subroot , i )
192
- }
193
- // Set value to subroot so that we verify next proof in chain commits to this subroot
194
- value = subroot
195
- case * ics23.CommitmentProof_Nonexist :
196
- return errorsmod .Wrapf (ErrInvalidProof ,
197
- "chained membership proof contains nonexistence proof at index %d. If this is unexpected, please ensure that proof was queried from a height that contained the value in store and was queried with the correct key. The key used: %s" ,
198
- i , keys )
199
- default :
200
- return errorsmod .Wrapf (ErrInvalidProof ,
201
- "expected proof type: %T, got: %T" , & ics23.CommitmentProof_Exist {}, proofs [i ].Proof )
168
+ subroot , err = proofs [i ].Calculate ()
169
+ if err != nil {
170
+ return errorsmod .Wrapf (ErrInvalidProof , "could not calculate proof root at index %d, merkle tree may be empty. %v" , i , err )
171
+ }
172
+
173
+ // Since keys are passed in from highest to lowest, we must grab their indices in reverse order
174
+ // from the proofs and specs which are lowest to highest
175
+ key , err := keys .GetKey (uint64 (len (keys .KeyPath ) - 1 - i ))
176
+ if err != nil {
177
+ return errorsmod .Wrapf (ErrInvalidProof , "could not retrieve key bytes for key %s: %v" , keys .KeyPath [len (keys .KeyPath )- 1 - i ], err )
202
178
}
179
+
180
+ ep := proofs [i ].GetExist ()
181
+ if ep == nil {
182
+ return errorsmod .Wrapf (ErrInvalidProof , "commitment proof must be existence proof. got: %T at index %d" , i , proofs [i ])
183
+ }
184
+
185
+ // verify membership of the proof at this index with appropriate key and value
186
+ if err := ep .Verify (specs [i ], subroot , key , value ); err != nil {
187
+ return errorsmod .Wrapf (ErrInvalidProof , "failed to verify membership proof at index %d: %v" , i , err )
188
+ }
189
+ // Set value to subroot so that we verify next proof in chain commits to this subroot
190
+ value = subroot
203
191
}
192
+
204
193
// Check that chained proof root equals passed-in root
205
194
if ! bytes .Equal (root , subroot ) {
206
- return errorsmod .Wrapf (ErrInvalidProof ,
207
- "proof did not commit to expected root: %X, got: %X. Please ensure proof was submitted with correct proofHeight and to the correct chain." ,
208
- root , subroot )
195
+ return errorsmod .Wrapf (ErrInvalidProof , "proof did not commit to expected root: %X, got: %X. Please ensure proof was submitted with correct proofHeight and to the correct chain." , root , subroot )
209
196
}
197
+
210
198
return nil
211
199
}
212
200
0 commit comments