diff --git a/go/ops.go b/go/ops.go index 5ddecc1..fffaa1a 100644 --- a/go/ops.go +++ b/go/ops.go @@ -166,6 +166,10 @@ func (op *InnerOp) CheckAgainstSpec(spec *ProofSpec, b int) error { return errors.New("spec.InnerSpec.ChildSize must be >= 1") } + if spec.InnerSpec.MaxPrefixLength >= spec.InnerSpec.MinPrefixLength+spec.InnerSpec.ChildSize { + return errors.New("spec.InnerSpec.MaxPrefixLength must be < spec.InnerSpec.MinPrefixLength + spec.InnerSpec.ChildSize") + } + // ensures soundness, with suffix having to be of correct length if len(op.Suffix)%int(spec.InnerSpec.ChildSize) != 0 { return fmt.Errorf("InnerOp suffix malformed") diff --git a/rust/src/verify.rs b/rust/src/verify.rs index ade0b93..f9df71f 100644 --- a/rust/src/verify.rs +++ b/rust/src/verify.rs @@ -203,7 +203,11 @@ fn ensure_inner(inner: &ics23::InnerOp, spec: &ics23::ProofSpec) -> Result<()> { ); ensure!( inner_spec.child_size > 0, - "spec.InnerSpec.ChildSize must be >= 1" + "spec.inner_spec.child_size must be >= 1" + ); + ensure!( + inner_spec.max_prefix_length < inner_spec.min_prefix_length + inner_spec.child_size, + "spec.inner_spec.max_prefix_length must be < spec.inner_spec.min_prefix_length + spec.inner_spec.child_size" ); ensure!( inner.suffix.len() % (inner_spec.child_size as usize) == 0, @@ -483,6 +487,13 @@ mod tests { let mut depth_limited_spec = api::iavl_spec(); depth_limited_spec.min_depth = 2; depth_limited_spec.max_depth = 4; + + let mut max_prefix_length_too_large_spec = api::iavl_spec(); + let inner_spec = max_prefix_length_too_large_spec + .inner_spec + .as_mut() + .unwrap(); + inner_spec.max_prefix_length = 100; let cases: HashMap<&'static str, ExistenceCase> = [ ( @@ -612,19 +623,32 @@ mod tests { proof: ExistenceProof { key: b"foo".to_vec(), value: b"bar".to_vec(), - leaf: Some(leaf), + leaf: Some(leaf.clone()), path: vec![ valid_inner.clone(), valid_inner.clone(), valid_inner.clone(), valid_inner.clone(), - valid_inner, + valid_inner.clone(), ], }, spec: depth_limited_spec, valid: false, }, ), + ( + "rejects inner spec with max prefix length >= min prefix lenght + child size", + ExistenceCase { + proof: ExistenceProof { + key: b"foo".to_vec(), + value: b"bar".to_vec(), + leaf: Some(leaf), + path: vec![valid_inner], + }, + spec: max_prefix_length_too_large_spec, + valid: false, + }, + ), ] .into_iter() .collect();