Skip to content

Commit

Permalink
Add Ed25519Verify_Bare (#426)
Browse files Browse the repository at this point in the history
* Add ed25519verify_bare

* Fix typos in Ed25519 docstrings (#2)

* Add crypto doc for Ed25519Verify_Bare

Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>
  • Loading branch information
jdtzmn and michaeldiamant authored Jun 30, 2022
1 parent 6e83ae6 commit 594e8e4
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 4 deletions.
3 changes: 2 additions & 1 deletion docs/crypto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Operator Cost Description
: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`
:code:`Ed25519Verify(d, s, p)` `1900`\* `1` if :code:`s` is the signature of the concatenation :code:`("ProgData" + hash_of_current_program + d)` signed by the private key corresponding to the public key :code:`p`, else `0`
:code:`Ed25519Verify_Bare(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`
:code:`EcdsaVerify(c, d, r, s, pk)` `1700` `1` if :code:`(r, s)` is the signature of :code:`d` by private key corresponding to public key :code:`pk`, else 0
:code:`EcdsaDecompress(c, short_pk)` `650` produces the decompressed public key associated with the compressed public key :code:`short_pk`
:code:`EcdsaRecover(c, d, id, r, s)` `2000` produces the public key associated with the signature :code:`(r, s)` and recovery id :code:`id`
Expand Down
1 change: 1 addition & 0 deletions pyteal/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ __all__ = [
"EcdsaRecover",
"EcdsaVerify",
"Ed25519Verify",
"Ed25519Verify_Bare",
"EnumInt",
"Eq",
"Err",
Expand Down
9 changes: 8 additions & 1 deletion pyteal/ast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@
from pyteal.ast.base64decode import Base64Decode

# ternary ops
from pyteal.ast.ternaryexpr import Divw, Ed25519Verify, SetBit, SetByte
from pyteal.ast.ternaryexpr import (
Divw,
Ed25519Verify,
Ed25519Verify_Bare,
SetBit,
SetByte,
)
from pyteal.ast.substring import Substring, Extract, Suffix
from pyteal.ast.replace import Replace
from pyteal.ast.jsonref import JsonRef
Expand Down Expand Up @@ -228,6 +234,7 @@
"GetBit",
"GetByte",
"Ed25519Verify",
"Ed25519Verify_Bare",
"Substring",
"Extract",
"Suffix",
Expand Down
22 changes: 20 additions & 2 deletions pyteal/ast/ternaryexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def Ed25519Verify(data: Expr, sig: Expr, key: Expr) -> TernaryExpr:
"""Verify the ed25519 signature of the concatenation ("ProgData" + hash_of_current_program + data).
Args:
data: The data signed by the public key. Must evalutes to bytes.
data: The data signed by the public key. Must evaluate to bytes.
sig: The proposed 64-byte signature of the concatenation ("ProgData" + hash_of_current_program + data).
Must evalute to bytes.
Must evaluate to bytes.
key: The 32 byte public key that produced the signature. Must evaluate to bytes.
"""
return TernaryExpr(
Expand All @@ -77,6 +77,24 @@ def Ed25519Verify(data: Expr, sig: Expr, key: Expr) -> TernaryExpr:
)


def Ed25519Verify_Bare(data: Expr, sig: Expr, key: Expr) -> TernaryExpr:
"""Verify the ed25519 signature of the data against the public key.
Args:
data: The data signed by the public key. Must evaluate to bytes.
sig: The proposed 64-byte signature of the data. Must evaluate to bytes.
key: The 32 byte public key that produced the signature. Must evaluate to bytes.
"""
return TernaryExpr(
Op.ed25519verify_bare,
(TealType.bytes, TealType.bytes, TealType.bytes),
TealType.uint64,
data,
sig,
key,
)


def SetBit(value: Expr, index: Expr, newBitValue: Expr) -> TernaryExpr:
"""Set the bit value of an expression at a specific index.
Expand Down
36 changes: 36 additions & 0 deletions pyteal/ast/ternaryexpr_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_ed25519verify():
Expand Down Expand Up @@ -41,6 +42,41 @@ def test_ed25519verify_invalid():
pt.Ed25519Verify(pt.Bytes("data"), pt.Bytes("sig"), pt.Int(0))


def test_ed25519verify_bare():
args = [pt.Bytes("data"), pt.Bytes("sig"), pt.Bytes("key")]
expr = pt.Ed25519Verify_Bare(args[0], args[1], args[2])
assert expr.type_of() == pt.TealType.uint64

expected = pt.TealSimpleBlock(
[
pt.TealOp(args[0], pt.Op.byte, '"data"'),
pt.TealOp(args[1], pt.Op.byte, '"sig"'),
pt.TealOp(args[2], pt.Op.byte, '"key"'),
pt.TealOp(expr, pt.Op.ed25519verify_bare),
]
)

actual, _ = expr.__teal__(teal7Options)
actual.addIncoming()
actual = pt.TealBlock.NormalizeBlocks(actual)

assert actual == expected

with pytest.raises(pt.TealInputError):
expr.__teal__(teal6Options)


def test_ed25519verify_bare_invalid():
with pytest.raises(pt.TealTypeError):
pt.Ed25519Verify_Bare(pt.Int(0), pt.Bytes("sig"), pt.Bytes("key"))

with pytest.raises(pt.TealTypeError):
pt.Ed25519Verify_Bare(pt.Bytes("data"), pt.Int(0), pt.Bytes("key"))

with pytest.raises(pt.TealTypeError):
pt.Ed25519Verify_Bare(pt.Bytes("data"), pt.Bytes("sig"), pt.Int(0))


def test_set_bit_int():
args = [pt.Int(0), pt.Int(2), pt.Int(1)]
expr = pt.SetBit(args[0], args[1], args[2])
Expand Down
1 change: 1 addition & 0 deletions pyteal/ir/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ def min_version(self) -> int:
replace3 = OpType("replace3", Mode.Signature | Mode.Application, 7)
base64_decode = OpType("base64_decode", Mode.Application | Mode.Signature, 7)
json_ref = OpType("json_ref", Mode.Signature | Mode.Application, 7)
ed25519verify_bare = OpType("ed25519verify_bare", Mode.Signature | Mode.Application, 7)
sha3_256 = OpType("sha3_256", Mode.Signature | Mode.Application, 7)
vrf_verify = OpType("vrf_verify", Mode.Signature | Mode.Application, 7)
block = OpType("block", Mode.Signature | Mode.Application, 7)
Expand Down

0 comments on commit 594e8e4

Please sign in to comment.