While poking around in the repositories I wondered how the sha2_256
algorithm was implemented in the PlutusTx
module. I followed all the imports and got the following path
- The
sha2_256
function inPlutusTx.Builtins
is defined at (1). In this module it is imported from a internal module with import nameBI
.
{-# INLINABLE sha2_256 #-}
-- | The SHA2-256 hash of a 'ByteString'
sha2_256 :: BuiltinByteString -> BuiltinByteString
sha2_256 = BI.sha2_256
- This
BI.sha2_256
function in thePlutusTx.Builtins.Internal
is defined at (2). Here the function is wrapped in theBuiltinByteString
type. A function is imported from the theHash
module.
{-# NOINLINE sha2_256 #-}
sha2_256 :: BuiltinByteString -> BuiltinByteString
sha2_256 (BuiltinByteString b) = BuiltinByteString $ Hash.sha2 b
- This
Hash.sha2
function in theData.ByteString.Hash
is defined at (3). Here it gets a bit more complicated. A cryptographic hash function takes an arbitrary block of data and calculates a fixed-size bit string (the digest). Since there may be other hash function (like the SHA3_256 version inPlutusTx
) the function is abstracted to a general hash function where the type inferred by the type application@SHA256
). This data type and its instance of a hash algorithm is imported fromCardano.Crypto.Hash.SHA256
.
-- | Hash a [[BSL.ByteString]] using the SHA-256 hash function.
sha2 :: BS.ByteString -> BS.ByteString
sha2 = digest (Proxy @SHA256)
- In this cardano-base package the module
Cardano.Crypto.Hash.SHA256
defines the data typeSHA256
and its instance of a hash algorithm at (4). The functionsha256_libsodium
is also defined there. This function uses another function calledc_crypto_hash_sha256
, this is where it gets interesting imported from the moduleLibsodium.C
.
data SHA256
instance HashAlgorithm SHA256 where
type SizeHash SHA256 = 32
hashAlgorithmName _ = "sha256"
digest _ = sha256_libsodium
- The function
c_crypto_hash_sha256
inCardano.Crypto.Libsodium.C
(like many other cryothographic derivatives used in cardano) is defined in (5). Here this function is actually import from the package Libsodium which is a library for encryption, decryption, signatures, password hashing and more written in C.
Now my question is, how is this lower level C function get used in the lower level Fμω lambda calculus onchain? Does each node just invoke/inject the C function once the lambda calculus references it?