diff --git a/gitlab-pages/docs/reference/crypto.md b/gitlab-pages/docs/reference/crypto.md new file mode 100644 index 000000000..571c0265b --- /dev/null +++ b/gitlab-pages/docs/reference/crypto.md @@ -0,0 +1,155 @@ +--- +id: crypto-reference +title: Crypto +--- + +## Crypto.black2b(data: bytes): bytes + +Runs the [blake2b hash algorithm](https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2) +over the given `bytes` data and returns a `bytes` representing the hash. + + + + + +```pascaligo +function hasherman_blake (const s: bytes) : bytes is blake2b(s) +``` + + + +```cameligo +let hasherman_blake (s: bytes) : bytes = Crypto.blake2b s +``` + + + +```reasonligo +let hasherman_blake = (s: bytes) => Crypto.blake2b(s); +``` + + + +## Crypto.sha256(data: bytes) : bytes + +Runs the [sha256 hash algorithm](https://en.wikipedia.org/wiki/SHA-2) over the given +`bytes` data and returns a `bytes` representing the hash. + + + + +```pascaligo +function hasherman (const s : bytes) : bytes is + begin skip end with sha_256(s) +``` + + +```cameligo +let hasherman (s : bytes) : bytes = + Crypto.sha256 s +``` + + +```reasonligo +let hasherman = (s: bytes): bytes => Crypto.sha256(s); +``` + + + +## Crypto.sha512(data: bytes) : bytes + +Runs the [sha512 hash algorithm](https://en.wikipedia.org/wiki/SHA-2) over the given +`bytes` data and returns a `bytes` representing the hash. + + + + + +```pascaligo +function hasherman512 (const s: bytes) : bytes is sha_512(s) +``` + + + +```cameligo +let hasherman512 (s: bytes) : bytes = Crypto.sha512 s +``` + + + +```reasonligo +let hasherman512 = (s: bytes) => Crypto.sha512(s); +``` + + + +## Crypto.hash_key(k: key) : key_hash + +Hashes a key for easy comparison and storage. + + + + +```pascaligo +function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash is block { + var ret : bool := False ; + var kh2 : key_hash := crypto_hash_key(k2) ; + if kh1 = kh2 then ret := True else skip; +} with (ret, kh2) +``` + + +```cameligo +let check_hash_key (kh1, k2: key_hash * key) : bool * key_hash = + let kh2 : key_hash = Crypto.hash_key k2 in + if kh1 = kh2 + then (true, kh2) + else (false, kh2) +``` + + +```reasonligo +let check_hash_key = ((kh1, k2): (key_hash, key)) : (bool, key_hash) => { + let kh2 : key_hash = Crypto.hash_key(k2); + if (kh1 == kh2) { + (true, kh2); + } + else { + (false, kh2); + } +}; +``` + + + +## Crypto.check(pk: key, signed: signature, data: bytes) : bool + +Check that a message has been signed by a particular key. + +> ⚠️ There is no way to *generate* a signed message in LIGO. This is because that would require storing a private key on chain, at which point it isn't very private anymore. + + + + +```pascaligo +function check_signature + (const pk: key; + const signed: signature; + const msg: bytes) : bool + is crypto_check(pk, signed, msg) +``` + + +```cameligo +let check_signature (pk, signed, msg: key * signature * bytes) : bool = + Crypto.check pk signed msg +``` + + +```reasonligo +let check_signature = ((pk, signed, msg): (key, signature, bytes)) : bool => { + Crypto.check(pk, signed, msg); +}; +``` + + diff --git a/src/passes/operators/operators.ml b/src/passes/operators/operators.ml index 6c8c92112..e6eb15c3e 100644 --- a/src/passes/operators/operators.ml +++ b/src/passes/operators/operators.ml @@ -162,7 +162,7 @@ module Simplify = struct | "failwith" -> ok C_FAILWITH | "Crypto.hash" -> ok C_HASH - | "Crypto.black2b" -> ok C_BLAKE2b + | "Crypto.blake2b" -> ok C_BLAKE2b | "Crypto.sha256" -> ok C_SHA256 | "Crypto.sha512" -> ok C_SHA512 | "Crypto.hash_key" -> ok C_HASH_KEY diff --git a/src/test/contracts/crypto.ligo b/src/test/contracts/crypto.ligo new file mode 100644 index 000000000..4e08f7b16 --- /dev/null +++ b/src/test/contracts/crypto.ligo @@ -0,0 +1,3 @@ +function hasherman512 (const s: bytes) : bytes is sha_512(s) + +function hasherman_blake (const s: bytes) : bytes is blake2b(s) diff --git a/src/test/contracts/crypto.mligo b/src/test/contracts/crypto.mligo new file mode 100644 index 000000000..9fa7e99e8 --- /dev/null +++ b/src/test/contracts/crypto.mligo @@ -0,0 +1,2 @@ +let hasherman512 (s: bytes) : bytes = Crypto.sha512 s +let hasherman_blake (s: bytes) : bytes = Crypto.blake2b s diff --git a/src/test/contracts/crypto.religo b/src/test/contracts/crypto.religo new file mode 100644 index 000000000..c5b17ce8e --- /dev/null +++ b/src/test/contracts/crypto.religo @@ -0,0 +1,2 @@ +let hasherman512 = (s: bytes) => Crypto.sha512(s); +let hasherman_blake = (s: bytes) => Crypto.blake2b(s); diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 2449e085e..58b492fc2 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -428,6 +428,48 @@ let bytes_arithmetic () : unit result = let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b3 , b1) in ok () +let crypto () : unit result = + let%bind program = type_file "./contracts/crypto.ligo" in + let%bind foo = e_bytes_hex "0f00" in + let%bind foototo = e_bytes_hex "0f007070" in + let%bind b1 = Test_helpers.run_typed_program_with_simplified_input program "hasherman512" foo in + let%bind () = expect_eq program "hasherman512" foo b1 in + let%bind b2 = Test_helpers.run_typed_program_with_simplified_input program "hasherman512" foototo in + let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b2 , b1) in + let%bind b4 = Test_helpers.run_typed_program_with_simplified_input program "hasherman_blake" foo in + let%bind () = expect_eq program "hasherman_blake" foo b4 in + let%bind b5 = Test_helpers.run_typed_program_with_simplified_input program "hasherman_blake" foototo in + let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b5 , b4) in + ok () + +let crypto_mligo () : unit result = + let%bind program = mtype_file "./contracts/crypto.mligo" in + let%bind foo = e_bytes_hex "0f00" in + let%bind foototo = e_bytes_hex "0f007070" in + let%bind b1 = Test_helpers.run_typed_program_with_simplified_input program "hasherman512" foo in + let%bind () = expect_eq program "hasherman512" foo b1 in + let%bind b2 = Test_helpers.run_typed_program_with_simplified_input program "hasherman512" foototo in + let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b2 , b1) in + let%bind b4 = Test_helpers.run_typed_program_with_simplified_input program "hasherman_blake" foo in + let%bind () = expect_eq program "hasherman_blake" foo b4 in + let%bind b5 = Test_helpers.run_typed_program_with_simplified_input program "hasherman_blake" foototo in + let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b5 , b4) in + ok () + +let crypto_religo () : unit result = + let%bind program = retype_file "./contracts/crypto.religo" in + let%bind foo = e_bytes_hex "0f00" in + let%bind foototo = e_bytes_hex "0f007070" in + let%bind b1 = Test_helpers.run_typed_program_with_simplified_input program "hasherman512" foo in + let%bind () = expect_eq program "hasherman512" foo b1 in + let%bind b2 = Test_helpers.run_typed_program_with_simplified_input program "hasherman512" foototo in + let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b2 , b1) in + let%bind b4 = Test_helpers.run_typed_program_with_simplified_input program "hasherman_blake" foo in + let%bind () = expect_eq program "hasherman_blake" foo b4 in + let%bind b5 = Test_helpers.run_typed_program_with_simplified_input program "hasherman_blake" foototo in + let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b5 , b4) in + ok () + let bytes_arithmetic_mligo () : unit result = let%bind program = mtype_file "./contracts/bytes_arithmetic.mligo" in let%bind foo = e_bytes_hex "0f00" in @@ -2189,8 +2231,7 @@ let main = test_suite "Integration (End to End)" [ test "bool (religo)" bool_expression_religo ; test "arithmetic" arithmetic ; test "arithmetic (mligo)" arithmetic_mligo ; - test "arithmetic (religo)" arithmetic_religo ; - test "bitwise_arithmetic" bitwise_arithmetic ; + test "arithmetic (religo)" arithmetic_religo ; test "bitwise_arithmetic" bitwise_arithmetic ; test "bitwise_arithmetic (mligo)" bitwise_arithmetic_mligo; test "bitwise_arithmetic (religo)" bitwise_arithmetic_religo; test "string_arithmetic" string_arithmetic ; @@ -2199,6 +2240,9 @@ let main = test_suite "Integration (End to End)" [ test "bytes_arithmetic" bytes_arithmetic ; test "bytes_arithmetic (mligo)" bytes_arithmetic_mligo ; test "bytes_arithmetic (religo)" bytes_arithmetic_religo ; + test "crypto" crypto ; + test "crypto (mligo)" crypto_mligo ; + test "crypto (religo)" crypto_religo ; test "set_arithmetic" set_arithmetic ; test "set_arithmetic (mligo)" set_arithmetic_mligo ; test "set_arithmetic (religo)" set_arithmetic_religo ;