Overview

Blinded dictionaries represent a partial reveal of a hash-committed dictionary. Consider the following example: Alice and Bob are playing the game of Battle at Sea. Alice constructs her flotilla as a dictionary of cell coordinates mapped to a boolean value representing presence or absence of a ship. Prior to starting the game, Alice sends Bob a hash commitment to the layout of her flotilla (she can use the _value_id function to retrieve the hash of her dictionary). For each move that Bob makes, Alice is able to provide a blinded dictionary that corresponds in structure to the original flotilla, but only reveals some portion of it, hiding (blinding) the others.

Constructing a Blinded Dictionary

Given a dictionary A, a blinded dictionary is constructed using the function _construct_blinded_dictionary, whose first argument is A and the second argument is a set of arrays representing sequences of indices into A that must be revealed.

A is any->>any = [[1,2],[3,4]]. 
B = _construct_blinded_dictionary A ([0,0],[1,1]).

In the code above, A is a two-dimensional array, and B is a blinded dictionary that reveals two out of four elements of A, namely, element A[0][0] and A[1][1]

Verifying the Blinded Dictionary

All data in MUFL is hash-addressed, so different blinded dictionaries always have different values of _value_id. In order to match the root hash of a blinded dictionary with the original dictionary, use the function called _root_hash. This _assert will succeed in the context of the above code example:

_assert (_value_id A == _root_hash B).

To verify elements of the blinded dictionary you can use normal subscripting syntax:

_assert (A 1 1 == B 1 1). 
_assert (B 0 1 == NIL). // because element [0,1] is blinded

MUFL currently does not support proof of element non-existence.

Impeding Attacks

Blinded dictionaries reveal information about the structure of the original dictionary that sometimes allow the attacker to infer the keys or values used on blinded branches. In order to increase security, developers are invited to salt both the indices and values in the dictionaries used for hash commitments. Recall that dictionaries may serve as keys into dictionaries. Consequently to salt keys, you need to replace a single key with a tuple [key,salt]. Keeping a list of salt values indexed by the original key enables you to reliably reveal elements later.