Safe Haskell | None |
---|---|
Language | Haskell2010 |
Timelock puzzle algorithms implementation.
This module follows the reference implementation for the most part, which you can find in the [tezos repository](https:/gitlab.comtezostezos-blobb1a2ff0334405cafd7465bfa991d23844f0b4e70srclib_crypto/timelock.ml).
For a more high-level overview of the concepts, refer to the timelock documentation page.
The general idea is built upon Rivest, Shamir, Wagner "Time-lock puzzles and timed-release Crypto", there are however some differences from the paper:
- The paper suggests using RC5 cipher, which Tezos implementation eschews in favor of NaCl's "secret box".
- The paper suggest generating the symmetric secret key \(K\) directly, then encrypting it with a randomly chosen value \(a\) as \(C_K = K + a^{2^t} \pmod n\). Tezos implementation instead randomly generates only \(a\), and then produces the secret key using BLAKE2b KDF with a fixed key from \(a^{2^t} \pmod n\).
- Since the secret key is determined only by the "unlocked" value, the time-locked value representation also differs. In the paper it's represented as ((n,a,t,C_K,C_M)), i.e. the tuple of modulus, "locked" value, time, encrypted key and encrypted message. In Tezos implementation it's instead ((a,n,C_M)), and \(t\) is treated as a separate argument.
- Likely to guard the protocol from guessing attacks, additional "proof" verification is added, described in [Boneh, Bünz, Fisch "A Survey of Two Verifiable Delay Functions"](https:/eprint.iacr.org2018/712.pdf)
Synopsis
- newtype TLTime where
- data Chest = Chest {
- chestLockedVal :: Locked
- chestPublicModulus :: PublicModulus
- chestCiphertext :: Ciphertext
- data ChestKey = ChestKey {
- ckUnlockedVal :: Unlocked
- ckProof :: Proof
- data Ciphertext = Ciphertext {
- ctNonce :: Nonce
- ctPayload :: ByteString
- data OpeningResult
- createChestAndChestKey :: ByteString -> TLTime -> IO (Chest, ChestKey)
- createChestKey :: Chest -> TLTime -> ChestKey
- chestBytes :: Chest -> ByteString
- chestKeyBytes :: ChestKey -> ByteString
- chestFromBytes :: ByteString -> Either Text Chest
- chestKeyFromBytes :: ByteString -> Either Text ChestKey
- openChest :: Chest -> ChestKey -> TLTime -> OpeningResult
- mkTLTime :: Integral i => i -> Either Text TLTime
- toTLTime :: (Integral a, CheckIntSubType a Word62) => a -> TLTime
- createChestAndChestKeyFromSeed :: Int -> ByteString -> TLTime -> (Chest, ChestKey)
Documentation
Number of steps a timelock needs to be opened without knowing a "secret", i.e. modulo factorization.
The reference implementation uses OCaml int
, and it can only be positive,
so on 64-bit architecture it's actually a 62-bit natural. We use Word62
to represent it.
The constructor is marked Unsafe since GHC does not warn on overflowing
literals (exceeding custom Word62
type bounds), thus the resultant
TLTime
value may get truncated silently.
>>>
UnsafeTLTime 4611686018427387906
UnsafeTLTime {unTLTime = 2}
A locked chest
Chest | |
|
Instances
Eq Chest Source # | |
Show Chest Source # | |
Generic Chest Source # | |
NFData Chest Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
Binary Chest Source # | |
IsoValue Chest Source # | |
TypeHasDoc Chest Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc | |
HasRPCRepr Chest Source # | |
Defined in Morley.AsRPC | |
type Rep Chest Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
type ToT Chest Source # | |
Defined in Morley.Michelson.Typed.Haskell.Value | |
type TypeDocFieldDescriptions Chest Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc | |
type AsRPC Chest Source # | |
Defined in Morley.AsRPC |
A chest "key" with proof that it was indeed opened fairly.
ChestKey | |
|
Instances
Eq ChestKey Source # | |
Show ChestKey Source # | |
Generic ChestKey Source # | |
NFData ChestKey Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
Binary ChestKey Source # | |
IsoValue ChestKey Source # | |
TypeHasDoc ChestKey Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc typeDocName :: Proxy ChestKey -> Text Source # typeDocMdDescription :: Markdown Source # typeDocMdReference :: Proxy ChestKey -> WithinParens -> Markdown Source # typeDocDependencies :: Proxy ChestKey -> [SomeDocDefinitionItem] Source # typeDocHaskellRep :: TypeDocHaskellRep ChestKey Source # typeDocMichelsonRep :: TypeDocMichelsonRep ChestKey Source # | |
HasRPCRepr ChestKey Source # | |
Defined in Morley.AsRPC | |
type Rep ChestKey Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
type ToT ChestKey Source # | |
Defined in Morley.Michelson.Typed.Haskell.Value | |
type TypeDocFieldDescriptions ChestKey Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc | |
type AsRPC ChestKey Source # | |
Defined in Morley.AsRPC |
data Ciphertext Source #
Ciphertext with nonce.
Ciphertext | |
|
Instances
Eq Ciphertext Source # | |
Defined in Morley.Tezos.Crypto.Timelock (==) :: Ciphertext -> Ciphertext -> Bool # (/=) :: Ciphertext -> Ciphertext -> Bool # | |
Show Ciphertext Source # | |
Defined in Morley.Tezos.Crypto.Timelock showsPrec :: Int -> Ciphertext -> ShowS # show :: Ciphertext -> String # showList :: [Ciphertext] -> ShowS # | |
Generic Ciphertext Source # | |
Defined in Morley.Tezos.Crypto.Timelock type Rep Ciphertext :: Type -> Type # from :: Ciphertext -> Rep Ciphertext x # to :: Rep Ciphertext x -> Ciphertext # | |
NFData Ciphertext Source # | |
Defined in Morley.Tezos.Crypto.Timelock rnf :: Ciphertext -> () # | |
Binary Ciphertext Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
type Rep Ciphertext Source # | |
Defined in Morley.Tezos.Crypto.Timelock |
data OpeningResult Source #
The result of opening the chest.
Correct ByteString | The chest was opened correctly. |
BogusCipher | The chest was opened correctly, but the contents do not decode with the given symmetric key. |
BogusOpening | The chest was not opened correctly, i.e. proof verification failed. |
Instances
Eq OpeningResult Source # | |
Defined in Morley.Tezos.Crypto.Timelock (==) :: OpeningResult -> OpeningResult -> Bool # (/=) :: OpeningResult -> OpeningResult -> Bool # | |
Show OpeningResult Source # | |
Defined in Morley.Tezos.Crypto.Timelock showsPrec :: Int -> OpeningResult -> ShowS # show :: OpeningResult -> String # showList :: [OpeningResult] -> ShowS # |
createChestAndChestKey Source #
:: ByteString | Chest content |
-> TLTime | Time (in elementary actions) to open without key. |
-> IO (Chest, ChestKey) |
Create a timelock puzzle and a key.
chestBytes :: Chest -> ByteString Source #
Convert a Chest
to binary representation, used by Tezos
chestKeyBytes :: ChestKey -> ByteString Source #
Convert a ChestKey
to binary representation, used by Tezos
chestFromBytes :: ByteString -> Either Text Chest Source #
Read a Chest
from binary representation, used by Tezos
chestKeyFromBytes :: ByteString -> Either Text ChestKey Source #
Read a ChestKey
from binary representation, used by Tezos
openChest :: Chest -> ChestKey -> TLTime -> OpeningResult Source #
Try to (quickly) open a chest with the given key, verifying the proof.
mkTLTime :: Integral i => i -> Either Text TLTime Source #
Safely creates TLTime
checking for
overflow and underflow. Accepts a number of any type.
toTLTime :: (Integral a, CheckIntSubType a Word62) => a -> TLTime Source #
Safely creates TLTime
.
This is the recommended way to create TLTime
values.
When constructing literals, you'll need to specify the type of the literal.
Bear in mind that GHC will check for literal overflow on builtin types like
Word16
and Word32
, but not on Word62
, so be aware that toTLTime
from
Word62
will overflow silently. Prefer using builtin types when possible.
>>>
unTLTime $ toTLTime (4611686018427387903 :: Word62)
4611686018427387903>>>
unTLTime $ toTLTime (4611686018427387904 :: Word62)
0
Internal, not safe for cryptography
createChestAndChestKeyFromSeed Source #
:: Int | Pseudo-random seed |
-> ByteString | Chest content |
-> TLTime | TLTime (in elementary actions) to open without key. |
-> (Chest, ChestKey) |
Construct a chest purely based on a seed for pseudorandom generator. This is not suitable for cryptography, used in tests.