Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Cryptographic primitives used in Tezos.
WARNING: some functions may be vulnerable to timing attacks.
Also, this code was not reviewed by cryptography/security experts.
Do not use it with secret keys that have some value.
We provide SecretKey
type and (limited) signing functionality only
for testing.
If you need to sign something in production, use something else
(e. g. octez-client
).
Tezos supports multiple cryptographic curves that are denoted by the number after tz in the public key hash: • tz1 — ed25519 • tz2 — secp256k1 • tz3 — P256 • tz4 — BLS12381 We have Morley.Tezos.Crypto.Curve module for each of these curves. They expose very similar functionality and their main purpose is to hide implementation details for each curve as well as some other specifics (e. g. prefixes that are used for human-readable representation).
Additionally, Tezos uses b2b hashes to represent addresses of contracts
(using KT1
prefix) and transaction rollups (using txr1
prefix) -- these
hashes are also implemented here.
We do not support txr1
addresses as those are disabled on the mainnet.
This module serves two purposes:
1. It is an umbrella module that re-exports some stuff from other modules.
2. Michelson types such as key
and signature
may store primitive of any
curve, so we need "union" types in Haskell as well.
During conversion to human-readable representation usually some magical prefix is used. They have been found in source code in some repos (e. g. https://gitlab.com/tezos/tezos/blob/c52ee69231c5ae4d9cec1f3c8aba0c3573922e2a/src/lib_crypto/base58.ml) and checked manually. Existing tests confirm they are correct.
Synopsis
- data PublicKey
- data SecretKey
- data Signature
- data HashTag (kind :: HashKind) where
- type KeyHashTag = HashTag 'HashKindPublicKey
- data Hash (kind :: HashKind) = Hash {
- hTag :: HashTag kind
- hBytes :: ByteString
- data HashKind
- type KeyHash = Hash 'HashKindPublicKey
- type ContractHash = Hash 'HashKindContract
- type SmartRollupHash = Hash 'HashKindSmartRollup
- data Bls12381Fr
- data Bls12381G1
- data Bls12381G2
- detSecretKey :: ByteString -> SecretKey
- detSecretKey' :: KeyType -> ByteString -> SecretKey
- data KeyType
- keyTypeTag :: KeyType -> Word8
- publicKeyType :: PublicKey -> KeyType
- toPublic :: SecretKey -> PublicKey
- publicKeyToBytes :: PublicKey -> ByteString
- signatureToBytes :: ByteArray ba => Signature -> ba
- mkSignature :: ByteArray ba => ba -> Maybe Signature
- parseSignatureRaw :: ByteString -> Either ParseSignatureRawError Signature
- signatureLengthBytes :: HasCallStack => Integral n => n
- checkSignature :: PublicKey -> Signature -> ByteString -> Bool
- sign :: MonadRandom m => SecretKey -> ByteString -> m Signature
- data CryptoParseError
- formatPublicKey :: PublicKey -> Text
- mformatPublicKey :: PublicKey -> MText
- parsePublicKey :: Text -> Either CryptoParseError PublicKey
- parsePublicKeyRaw :: ByteString -> Either Text PublicKey
- formatSignature :: Signature -> Text
- mformatSignature :: Signature -> MText
- parseSignature :: Text -> Either CryptoParseError Signature
- formatHash :: Hash kind -> Text
- mformatHash :: Hash kind -> MText
- parseHash :: AllHashTags kind => Text -> Either CryptoParseError (Hash kind)
- parseKeyHashRaw :: ByteString -> Either CryptoParseError KeyHash
- hashLengthBytes :: Integral n => n
- formatSecretKey :: SecretKey -> Text
- parseSecretKey :: Text -> Either CryptoParseError SecretKey
- decodeKeyHash :: ExceptT CryptoParseError Get KeyHash
- hashKey :: PublicKey -> KeyHash
- blake2b :: ByteString -> ByteString
- blake2b160 :: ByteString -> ByteString
- keccak :: ByteString -> ByteString
- sha256 :: ByteString -> ByteString
- sha3 :: ByteString -> ByteString
- sha512 :: ByteString -> ByteString
- data Chest
- data ChestKey
- data OpeningResult
- newtype TLTime where
- UnsafeTLTime {
- unTLTime :: Word62
- pattern TLTime :: Word62 -> TLTime
- UnsafeTLTime {
- openChest :: Chest -> ChestKey -> TLTime -> OpeningResult
- mkTLTime :: Integral i => i -> Either Text TLTime
- toTLTime :: (Integral a, CheckIntSubType a Word62) => a -> TLTime
- encodeBase58Check :: ByteString -> Text
- decodeBase58Check :: Text -> Maybe ByteString
- data B58CheckWithPrefixError
- decodeBase58CheckWithPrefix :: ByteString -> Text -> Either B58CheckWithPrefixError ByteString
- parseSomeHashBase58 :: Text -> Either CryptoParseError (Some Hash)
- keyDecoders :: [TaggedDecoder PublicKey]
- keyHashDecoders :: (Monad (t Get), MonadTrans t) => [TaggedDecoderM t KeyHash]
- class AllHashTags kind where
- allHashTags :: NonEmpty (HashTag kind)
Cryptographic primitive types
Public cryptographic key used by Tezos. There are three cryptographic curves each represented by its own constructor.
PublicKeyEd25519 PublicKey | Public key that uses the ed25519 cryptographic curve. |
PublicKeySecp256k1 PublicKey | Public key that uses the secp256k1 cryptographic curve. |
PublicKeyP256 PublicKey | Public key that uses the NIST P-256 cryptographic curve. |
PublicKeyBLS PublicKey | Public key that uses the BLS12-381 cryptographic curve. |
Instances
Secret cryptographic key used by Tezos.
Constructors correspond to PublicKey
constructors.
SecretKeyEd25519 SecretKey | Secret key that uses the ed25519 cryptographic curve. |
SecretKeySecp256k1 SecretKey | Secret key that uses the secp256k1 cryptographic curve. |
SecretKeyP256 SecretKey | Secret key that uses the NIST P-256 cryptographic curve. |
SecretKeyBLS SecretKey | Secret key that uses BLS12-381 curve. |
Instances
Cryptographic signatures used by Tezos.
Constructors correspond to PublicKey
constructors.
Tezos distinguishes signatures for different curves. For instance, ed25519 signatures and secp256k1 signatures are printed differently (have different prefix). However, signatures are packed without information about the curve. For this purpose there is a generic signature which only stores bytes and doesn't carry information about the curve. Apparently unpacking from bytes always produces such signature. Unpacking from string produces a signature with curve information.
SignatureEd25519 Signature | Signature that uses the ed25519 cryptographic curve. |
SignatureSecp256k1 Signature | Siganture that uses the secp256k1 cryptographic curve. |
SignatureP256 Signature | Signature that uses the NIST P-256 cryptographic curve. |
SignatureBLS Signature | Signature that uses the BLS12-381 cryptographic curve. |
SignatureGeneric ByteString | Generic signature for which curve is unknown. |
Instances
data HashTag (kind :: HashKind) where Source #
What specific type of hash is used for the Hash
.
HashKey :: KeyType -> HashTag 'HashKindPublicKey | |
HashContract :: HashTag 'HashKindContract | |
HashSR :: HashTag 'HashKindSmartRollup |
Instances
Lift (HashTag kind :: Type) Source # | |
Show (HashTag kind) Source # | |
NFData (HashTag kind) Source # | |
Defined in Morley.Tezos.Crypto | |
Eq (HashTag kind) Source # | |
Ord (HashTag kind) Source # | |
Defined in Morley.Tezos.Crypto |
type KeyHashTag = HashTag 'HashKindPublicKey Source #
A compatibility synonym for a public key hash tag.
data Hash (kind :: HashKind) Source #
Blake2b_160 hash of something.
Hash | |
|
Instances
A kind of a hash.
HashKindPublicKey | Public key hash for |
HashKindContract | Contract hash for |
HashKindSmartRollup | Smart rollup hash for |
type KeyHash = Hash 'HashKindPublicKey Source #
Convenience synonym for an on-chain public key hash.
type ContractHash = Hash 'HashKindContract Source #
Convenience synonym for a contract hash.
type SmartRollupHash = Hash 'HashKindSmartRollup Source #
Convenience synonym for a smart rollup hash.
data Bls12381Fr Source #
An element of an algebraic number field (scalar), used for multiplying
Bls12381G1
and Bls12381G2
.
Instances
data Bls12381G1 Source #
G1 point on the curve.
Instances
data Bls12381G2 Source #
G2 point on the curve.
Instances
Public/secret key functions
detSecretKey :: ByteString -> SecretKey Source #
Deterministically generate a secret key from seed. Type of the key depends on seed value.
detSecretKey' :: KeyType -> ByteString -> SecretKey Source #
Deterministically generate a secret key from seed. Key type is specified explicitly.
Type of public/secret key as enum.
Instances
Bounded KeyType Source # | |
Enum KeyType Source # | |
Generic KeyType Source # | |
Show KeyType Source # | |
NFData KeyType Source # | |
Defined in Morley.Tezos.Crypto | |
Eq KeyType Source # | |
Ord KeyType Source # | |
Buildable KeyType Source # | |
Defined in Morley.Tezos.Crypto | |
Lift KeyType Source # | |
type Rep KeyType Source # | |
Defined in Morley.Tezos.Crypto type Rep KeyType = D1 ('MetaData "KeyType" "Morley.Tezos.Crypto" "morley-1.20.0-inplace" 'False) ((C1 ('MetaCons "KeyTypeEd25519" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "KeyTypeSecp256k1" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "KeyTypeP256" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "KeyTypeBLS" 'PrefixI 'False) (U1 :: Type -> Type))) |
keyTypeTag :: KeyType -> Word8 Source #
publicKeyType :: PublicKey -> KeyType Source #
Signature
mkSignature :: ByteArray ba => ba -> Maybe Signature Source #
Make a Signature
from raw bytes.
Can return only SignatureGeneric
or SignatureBLS
parseSignatureRaw :: ByteString -> Either ParseSignatureRawError Signature Source #
signatureLengthBytes :: HasCallStack => Integral n => n Source #
checkSignature :: PublicKey -> Signature -> ByteString -> Bool Source #
Check that a sequence of bytes has been signed with a given key.
sign :: MonadRandom m => SecretKey -> ByteString -> m Signature Source #
Formatting
data CryptoParseError Source #
Error that can happen during parsing of cryptographic primitive types.
Instances
Show CryptoParseError Source # | |
Defined in Morley.Tezos.Crypto.Util showsPrec :: Int -> CryptoParseError -> ShowS # show :: CryptoParseError -> String # showList :: [CryptoParseError] -> ShowS # | |
NFData CryptoParseError Source # | |
Defined in Morley.Tezos.Crypto.Util rnf :: CryptoParseError -> () # | |
Eq CryptoParseError Source # | |
Defined in Morley.Tezos.Crypto.Util (==) :: CryptoParseError -> CryptoParseError -> Bool # (/=) :: CryptoParseError -> CryptoParseError -> Bool # | |
Buildable CryptoParseError Source # | |
Defined in Morley.Tezos.Crypto.Util build :: CryptoParseError -> Doc buildList :: [CryptoParseError] -> Doc |
formatPublicKey :: PublicKey -> Text Source #
mformatPublicKey :: PublicKey -> MText Source #
formatSignature :: Signature -> Text Source #
mformatSignature :: Signature -> MText Source #
formatHash :: Hash kind -> Text Source #
mformatHash :: Hash kind -> MText Source #
parseHash :: AllHashTags kind => Text -> Either CryptoParseError (Hash kind) Source #
hashLengthBytes :: Integral n => n Source #
Length of a hash in bytes (only the hash itself, no tags, checksums or anything).
formatSecretKey :: SecretKey -> Text Source #
parseSecretKey :: Text -> Either CryptoParseError SecretKey Source #
Parse unencrypted secret key. It accepts formats containing
either with or without the unecrypted
prefix.
Hashing
blake2b :: ByteString -> ByteString Source #
Compute a cryptographic hash of a bytestring using the Blake2b_256 cryptographic hash function. It's used by the BLAKE2B instruction in Michelson.
blake2b160 :: ByteString -> ByteString Source #
Compute a cryptographic hash of a bytestring using the Blake2b_160 cryptographic hash function.
keccak :: ByteString -> ByteString Source #
Compute a cryptographic hash of a bytestring using the Keccak_256 cryptographic hash function. It is used by the KECCAK Michelson instruction.
sha256 :: ByteString -> ByteString Source #
Compute a cryptographic hash of a bytestring using the Sha256 cryptographic hash function.
sha3 :: ByteString -> ByteString Source #
Compute a cryptographic hash of a bytestring using the Sha3_256 cryptographic hash function. It is used by the SHA3 Michelson instruction.
sha512 :: ByteString -> ByteString Source #
Compute a cryptographic hash of a bytestring using the Sha512 cryptographic hash function.
Timelock puzzle
A locked chest
Instances
Generic Chest Source # | |
Show Chest Source # | |
Binary Chest Source # | |
NFData Chest Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
Eq Chest Source # | |
HasRPCRepr Chest Source # | |
Defined in Morley.AsRPC | |
TypeHasDoc Chest Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc | |
IsoValue Chest Source # | |
type Rep Chest Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
type AsRPC Chest Source # | |
Defined in Morley.AsRPC | |
type TypeDocFieldDescriptions Chest Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc | |
type ToT Chest Source # | |
Defined in Morley.Michelson.Typed.Haskell.Value |
A chest "key" with proof that it was indeed opened fairly.
Instances
Generic ChestKey Source # | |
Show ChestKey Source # | |
Binary ChestKey Source # | |
NFData ChestKey Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
Eq ChestKey Source # | |
HasRPCRepr ChestKey Source # | |
Defined in Morley.AsRPC | |
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 # | |
IsoValue ChestKey Source # | |
type Rep ChestKey Source # | |
Defined in Morley.Tezos.Crypto.Timelock | |
type AsRPC ChestKey Source # | |
Defined in Morley.AsRPC | |
type TypeDocFieldDescriptions ChestKey Source # | |
Defined in Morley.Michelson.Typed.Haskell.Doc | |
type ToT ChestKey Source # | |
Defined in Morley.Michelson.Typed.Haskell.Value |
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
Show OpeningResult Source # | |
Defined in Morley.Tezos.Crypto.Timelock showsPrec :: Int -> OpeningResult -> ShowS # show :: OpeningResult -> String # showList :: [OpeningResult] -> ShowS # | |
Eq OpeningResult Source # | |
Defined in Morley.Tezos.Crypto.Timelock (==) :: OpeningResult -> OpeningResult -> Bool # (/=) :: OpeningResult -> OpeningResult -> Bool # |
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}
UnsafeTLTime | |
|
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
Utilities
encodeBase58Check :: ByteString -> Text Source #
Encode a bytestring in Base58Check format.
decodeBase58Check :: Text -> Maybe ByteString Source #
Decode a bytestring from Base58Check format.
data B58CheckWithPrefixError Source #
Instances
Show B58CheckWithPrefixError Source # | |
Defined in Morley.Tezos.Crypto.Util showsPrec :: Int -> B58CheckWithPrefixError -> ShowS # show :: B58CheckWithPrefixError -> String # showList :: [B58CheckWithPrefixError] -> ShowS # |
decodeBase58CheckWithPrefix :: ByteString -> Text -> Either B58CheckWithPrefixError ByteString Source #
Parse a base58check encoded value expecting some prefix. If the actual prefix matches the expected one, it's stripped of and the resulting payload is returned.
parseSomeHashBase58 :: Text -> Either CryptoParseError (Some Hash) Source #
Parse a Hash
of any known kind from its its human-readable textual representation.
keyHashDecoders :: (Monad (t Get), MonadTrans t) => [TaggedDecoderM t KeyHash] Source #
class AllHashTags kind where Source #
allHashTags :: NonEmpty (HashTag kind) Source #
Instances
AllHashTags 'HashKindContract Source # | |
Defined in Morley.Tezos.Crypto | |
AllHashTags 'HashKindPublicKey Source # | |
Defined in Morley.Tezos.Crypto | |
AllHashTags 'HashKindSmartRollup Source # | |
Defined in Morley.Tezos.Crypto |