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] => #c0x944834111822843979ace19833d05ca9daf2f655230faec517433e72fe777b
Now Lurk knows that #c0x944834111822843979ace19833d05ca9daf2f655230faec517433e72fe777b
is a commitment to 123
and can successfully open it.
lurk-user> (open #c0x944834111822843979ace19833d05ca9daf2f655230faec517433e72fe777b)
[2 iterations] => 123
Lurk understands it if you use big nums in an open
expression directly.
lurk-user> (open #0x944834111822843979ace19833d05ca9daf2f655230faec517433e72fe777b)
[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] => #c0x483cd4ed61cb38d4722743fe470c4c81abf1a568ceae9423864d5acf03739f
For when hiding is unimportant, commit
creates commitments with a default secret of #0x0
.
lurk-user> (hide #0x0 123)
[3 iterations] => #c0x944834111822843979ace19833d05ca9daf2f655230faec517433e72fe777b
And both hashes above open to the same value 123
.
lurk-user> (open #c0x944834111822843979ace19833d05ca9daf2f655230faec517433e72fe777b)
[2 iterations] => 123
lurk-user> (open #c0x483cd4ed61cb38d4722743fe470c4c81abf1a568ceae9423864d5acf03739f)
[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] => #c0x64411a93ff0183cdbe7c2d0dbbbd69ac7b47c75aa1124a901207f3f47d0ce4
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 #c0x64411a93ff0183cdbe7c2d0dbbbd69ac7b47c75aa1124a901207f3f47d0ce4) 5)
[8 iterations] => 32
lurk-user> ((open #c0x64411a93ff0183cdbe7c2d0dbbbd69ac7b47c75aa1124a901207f3f47d0ce4) 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] => #c0x21aa7ddf7089aa62c98717d2634cf8d414f9b7b2d36c46d6a360ba754beff1
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 #c0x21aa7ddf7089aa62c98717d2634cf8d414f9b7b2d36c46d6a360ba754beff1)
(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.