Extend a key tree with a key.
(bip32-extend-tree tree parent-path child-index) → (mv error? new-tree)
The new key is identified by (i) the path of its parent and (ii) the child index of the new key. The parent must be already in the tree, while the new child key must not: this is expressed by the guard of this function. The total depth of the new key should not exceed 255: this is also expressed by the guard.
Given our model of key trees,
we just add the path of the new key to the underlying index tree.
But we need to check whether the child key derivation fails:
if it does, we return the input key tree unchanged,
along with
If the key tree consists of private keys, the new key is private. If the key tree consists of public keys, the new key is public. We uniformly use the bip32-ckd function.
Function:
(defun bip32-extend-tree (tree parent-path child-index) (declare (xargs :guard (and (bip32-key-treep tree) (ubyte32-listp parent-path) (ubyte32p child-index)))) (declare (xargs :guard (and (bip32-path-in-tree-p parent-path tree) (not (bip32-path-in-tree-p (rcons child-index parent-path) tree)) (< (+ (bip32-key-tree->root-depth tree) (len parent-path)) 255)))) (b* ((tree (mbe :logic (bip32-key-tree-fix tree) :exec tree)) (parent-path (mbe :logic (ubyte32-list-fix parent-path) :exec parent-path)) (child-index (mbe :logic (ubyte32-fix child-index) :exec child-index)) ((bip32-key-tree tree) tree) ((unless (mbt (bip32-path-in-tree-p parent-path tree))) (mv t tree)) (new-path (rcons child-index parent-path)) ((unless (mbt (not (bip32-path-in-tree-p new-path tree)))) (mv t tree)) ((unless (mbt (< (+ tree.root-depth (len parent-path)) 255))) (mv t tree)) ((mv error? &) (bip32-ckd* tree.root-key new-path)) ((when error?) (mv error? tree)) (new-index-tree (insert new-path tree.index-tree)) (new-tree (change-bip32-key-tree tree :index-tree new-index-tree))) (mv nil new-tree)))
Theorem:
(defthm booleanp-of-bip32-extend-tree.error? (b* (((mv ?error? ?new-tree) (bip32-extend-tree tree parent-path child-index))) (booleanp error?)) :rule-classes :rewrite)
Theorem:
(defthm bip32-key-treep-of-bip32-extend-tree.new-tree (b* (((mv ?error? ?new-tree) (bip32-extend-tree tree parent-path child-index))) (bip32-key-treep new-tree)) :rule-classes :rewrite)
Theorem:
(defthm bip32-key-tree->root-key-of-bip32-extend-tree (equal (bip32-key-tree->root-key (mv-nth 1 (bip32-extend-tree tree parent-path child-index))) (bip32-key-tree->root-key tree)))
Theorem:
(defthm bip32-key-tree->root-depth-of-bip32-extend-tree (equal (bip32-key-tree->root-depth (mv-nth 1 (bip32-extend-tree tree parent-path child-index))) (bip32-key-tree->root-depth tree)))
Theorem:
(defthm bip32-key-tree->root-index-of-bip32-extend-tree (equal (bip32-key-tree->root-index (mv-nth 1 (bip32-extend-tree tree parent-path child-index))) (bip32-key-tree->root-index tree)))
Theorem:
(defthm bip32-key-tree->root-parent-of-bip32-extend-tree (equal (bip32-key-tree->root-parent (mv-nth 1 (bip32-extend-tree tree parent-path child-index))) (bip32-key-tree->root-parent tree)))
Theorem:
(defthm bip32-key-tree->index-tree-of-bip32-extend-tree (b* (((mv error? tree1) (bip32-extend-tree tree parent-path child-index))) (equal (bip32-key-tree->index-tree tree1) (if error? (bip32-key-tree->index-tree tree) (insert (rcons (ubyte32-fix child-index) (ubyte32-list-fix parent-path)) (bip32-key-tree->index-tree tree))))))
Theorem:
(defthm bip32-key-tree-priv-p-of-bip32-extend-tree (equal (bip32-key-tree-priv-p (mv-nth 1 (bip32-extend-tree tree parent-path child-index))) (bip32-key-tree-priv-p tree)))
Theorem:
(defthm bip32-path-in-tree-p-of-bip32-extend-tree (b* (((mv error? new-key-tree) (bip32-extend-tree key-tree path index))) (implies (not error?) (bip32-path-in-tree-p (rcons index path) new-key-tree))))
Theorem:
(defthm bip32-extend-tree-of-bip32-key-tree-fix-tree (equal (bip32-extend-tree (bip32-key-tree-fix tree) parent-path child-index) (bip32-extend-tree tree parent-path child-index)))
Theorem:
(defthm bip32-extend-tree-bip32-key-tree-equiv-congruence-on-tree (implies (bip32-key-tree-equiv tree tree-equiv) (equal (bip32-extend-tree tree parent-path child-index) (bip32-extend-tree tree-equiv parent-path child-index))) :rule-classes :congruence)
Theorem:
(defthm bip32-extend-tree-of-ubyte32-list-fix-parent-path (equal (bip32-extend-tree tree (ubyte32-list-fix parent-path) child-index) (bip32-extend-tree tree parent-path child-index)))
Theorem:
(defthm bip32-extend-tree-ubyte32-list-equiv-congruence-on-parent-path (implies (acl2::ubyte32-list-equiv parent-path parent-path-equiv) (equal (bip32-extend-tree tree parent-path child-index) (bip32-extend-tree tree parent-path-equiv child-index))) :rule-classes :congruence)
Theorem:
(defthm bip32-extend-tree-of-ubyte32-fix-child-index (equal (bip32-extend-tree tree parent-path (ubyte32-fix child-index)) (bip32-extend-tree tree parent-path child-index)))
Theorem:
(defthm bip32-extend-tree-ubyte32-equiv-congruence-on-child-index (implies (acl2::ubyte32-equiv child-index child-index-equiv) (equal (bip32-extend-tree tree parent-path child-index) (bip32-extend-tree tree parent-path child-index-equiv))) :rule-classes :congruence)