Commitments

Lurk has built-in support for cryptographic commitments.

We can create a commitment to any Lurk data with commit.

lurk-user> (commit 123)
[2 iterations] => #c0x4a902d7be96d1021a473353bd59247ea4c0f0688b5bae0c833a1f624b77ede

Now Lurk knows that #c0x4a902d7be96d1021a473353bd59247ea4c0f0688b5bae0c833a1f624b77ede is a commitment to 123 and can successfully open it.

lurk-user> (open #c0x4a902d7be96d1021a473353bd59247ea4c0f0688b5bae0c833a1f624b77ede)
[2 iterations] => 123

Lurk understands it if you use big nums in an open expression directly.

lurk-user> (open #0x4a902d7be96d1021a473353bd59247ea4c0f0688b5bae0c833a1f624b77ede)
[2 iterations] => 123

Because Lurk commitments are based on Poseidon hashes (just as all compound data in Lurk is), it is computationally infeasible to discover a second preimage to the digest represented by a commitment. This means that Lurk commitments are (computationally) binding.

Lurk also supports explicit hiding commitments. The hiding secret must be a big num.

lurk-user> (hide #0x1 123)
[3 iterations] => #c0x2d42d50c445fe7021003b9d177e09e93008f97f74eea0f1c61c3f27aec104f

For when hiding is unimportant, commit creates commitments with a default secret of #0x0.

lurk-user> (hide #0x0 123)
[3 iterations] => #0x4a902d7be96d1021a473353bd59247ea4c0f0688b5bae0c833a1f624b77ede

And both hashes above open to the same value 123.

lurk-user> (open #0x4a902d7be96d1021a473353bd59247ea4c0f0688b5bae0c833a1f624b77ede)
[2 iterations] => 123
lurk-user> (open #c0x2d42d50c445fe7021003b9d177e09e93008f97f74eea0f1c61c3f27aec104f)
[2 iterations] => 123

Functional commitments

Again, we can commit to any Lurk data, including functions.

lurk-user> (commit (lambda (x) (+ 7 (* x x))))
[2 iterations] => #c0x8b10a9e88372ee05aea4230b21d7ed9b9e4b1d7f9d2a056d125172ad07c4fc

The above is a commitment to a function that squares its input then adds seven. Then we can open it and apply arguments as usual.

lurk-user> ((open #c0x8b10a9e88372ee05aea4230b21d7ed9b9e4b1d7f9d2a056d125172ad07c4fc) 5)
[8 iterations] => 32
lurk-user> ((open #c0x8b10a9e88372ee05aea4230b21d7ed9b9e4b1d7f9d2a056d125172ad07c4fc) 9)
[8 iterations] => 88

Higher-order functional commitments

Higher-order functions are no exceptions and can be committed to in the same manner.

Here, we commit to a function that receives a function as input and applies it to a secret internal value.

lurk-user> 
(let ((secret-data 222)
      (data-interface (lambda (f) (f secret-data))))
  (commit data-interface))
[5 iterations] => #c0x759b94bccb5545915690c4e847e0f3e5e42c732eafcc02cbcd55ac50066c9b

Now we can open it, applying it to a function that adds 111 to the secret value that the committed function hides.

lurk-user>
((open #c0x759b94bccb5545915690c4e847e0f3e5e42c732eafcc02cbcd55ac50066c9b)
 (lambda (data) (+ data 111)))
[10 iterations] => 333

We coin the term Higher-Order Functional Commitments, and as far as we are aware, Lurk is the first and only extant system enabling this powerful usage in the bare language.