From c16598a5acca41f92b7844704864b92b484902d8 Mon Sep 17 00:00:00 2001 From: Jacob Daitzman Date: Mon, 27 Jun 2022 14:58:55 -0400 Subject: [PATCH 1/2] Add sha3_256 --- pyteal/__init__.pyi | 1 + pyteal/ast/__init__.py | 2 ++ pyteal/ast/unaryexpr.py | 5 +++++ pyteal/ast/unaryexpr_test.py | 22 ++++++++++++++++++++++ pyteal/ir/ops.py | 1 + 5 files changed, 31 insertions(+) diff --git a/pyteal/__init__.pyi b/pyteal/__init__.pyi index 4fa32d071..a97314743 100644 --- a/pyteal/__init__.pyi +++ b/pyteal/__init__.pyi @@ -149,6 +149,7 @@ __all__ = [ "SetBit", "SetByte", "Sha256", + "Sha3_256", "Sha512_256", "ShiftLeft", "ShiftRight", diff --git a/pyteal/ast/__init__.py b/pyteal/ast/__init__.py index 613a39480..b61cba17e 100644 --- a/pyteal/ast/__init__.py +++ b/pyteal/ast/__init__.py @@ -45,6 +45,7 @@ BitLen, Sha256, Sha512_256, + Sha3_256, Keccak256, Not, BitwiseNot, @@ -189,6 +190,7 @@ "BitLen", "Sha256", "Sha512_256", + "Sha3_256", "Keccak256", "Not", "BitwiseNot", diff --git a/pyteal/ast/unaryexpr.py b/pyteal/ast/unaryexpr.py index 619bfab46..1fad9903b 100644 --- a/pyteal/ast/unaryexpr.py +++ b/pyteal/ast/unaryexpr.py @@ -80,6 +80,11 @@ def Sha512_256(arg: Expr) -> UnaryExpr: return UnaryExpr(Op.sha512_256, TealType.bytes, TealType.bytes, arg) +def Sha3_256(arg: Expr) -> UnaryExpr: + """Get the SHA3-256 hash of a byte string.""" + return UnaryExpr(Op.sha3_256, TealType.bytes, TealType.bytes, arg) + + def Keccak256(arg: Expr) -> UnaryExpr: """Get the KECCAK-256 hash of a byte string.""" return UnaryExpr(Op.keccak256, TealType.bytes, TealType.bytes, arg) diff --git a/pyteal/ast/unaryexpr_test.py b/pyteal/ast/unaryexpr_test.py index 50a6e2f15..5a096fcbd 100644 --- a/pyteal/ast/unaryexpr_test.py +++ b/pyteal/ast/unaryexpr_test.py @@ -7,6 +7,7 @@ teal4Options = pt.CompileOptions(version=4) teal5Options = pt.CompileOptions(version=5) teal6Options = pt.CompileOptions(version=6) +teal7Options = pt.CompileOptions(version=7) def test_btoi(): @@ -146,6 +147,27 @@ def test_sha512_256_invalid(): pt.Sha512_256(pt.Int(1)) +def test_sha3_256(): + arg = pt.Arg(0) + expr = pt.Sha3_256(arg) + assert expr.type_of() == pt.TealType.bytes + + expected = pt.TealSimpleBlock( + [pt.TealOp(arg, pt.Op.arg, 0), pt.TealOp(expr, pt.Op.sha3_256)] + ) + + actual, _ = expr.__teal__(teal7Options) + actual.addIncoming() + actual = pt.TealBlock.NormalizeBlocks(actual) + + assert actual == expected + + +def test_sha3_256_invalid(): + with pytest.raises(pt.TealTypeError): + pt.Sha3_256(pt.Int(1)) + + def test_keccak256(): arg = pt.Arg(0) expr = pt.Keccak256(arg) diff --git a/pyteal/ir/ops.py b/pyteal/ir/ops.py index 7d91dab42..ead46b0c1 100644 --- a/pyteal/ir/ops.py +++ b/pyteal/ir/ops.py @@ -179,6 +179,7 @@ def min_version(self) -> int: gitxnas = OpType("gitxnas", Mode.Application, 6) gloadss = OpType("gloadss", Mode.Application, 6) acct_params_get = OpType("acct_params_get", Mode.Application, 6) + sha3_256 = OpType("sha3_256", Mode.Signature | Mode.Application, 7) # fmt: on From 63fbfffb8262a06cbd067dbfac2e8d5b6aa7a95f Mon Sep 17 00:00:00 2001 From: Jacob Daitzman Date: Wed, 29 Jun 2022 10:33:57 -0400 Subject: [PATCH 2/2] Add crypto docs --- docs/crypto.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/crypto.rst b/docs/crypto.rst index d062eb671..2ae4055b1 100644 --- a/docs/crypto.rst +++ b/docs/crypto.rst @@ -14,6 +14,7 @@ Below is how you express cryptographic primitives in PyTeal: Operator Cost Description ==================================== ========= ================================================================================================================== :code:`Sha256(e)` `35` `SHA-256` hash function, produces 32 bytes +:code:`Sha3_256(e)` `130` `SHA3-256` hash function, produces 32 bytes :code:`Keccak256(e)` `130` `Keccak-256` hash funciton, produces 32 bytes :code:`Sha512_256(e)` `45` `SHA-512/256` hash function, produces 32 bytes :code:`Ed25519Verify(d, s, p)` `1900`\* `1` if :code:`s` is the signature of :code:`d` signed by the private key corresponding to the public key :code:`p`, else `0`