Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
efae689
Merge branch 'release/v1.14.1'
algojack Mar 29, 2022
6b6dfc0
Merge branch 'release/v1.15.0'
algobarb Apr 28, 2022
7c7bab4
Merge branch 'release/v1.16.0'
onetechnical Jun 3, 2022
fae5b08
Merge branch 'release/v1.17.0'
egieseke Jun 21, 2022
f65c7dc
Merge branch 'release/v1.18.0'
algojack Jul 27, 2022
7dc2807
Merge branch 'release/v1.19.0'
algobarb Aug 17, 2022
16bee7a
deprecate stuffs, prototype SanityCheckProgram
ahangsu Aug 19, 2022
0a4d661
Merge branch 'master' into deprecate-langspec
ahangsu Aug 19, 2022
4d5562f
remove commented deprecated code
ahangsu Aug 22, 2022
79db247
docstring for sanitycheckprogram
ahangsu Aug 22, 2022
a29f082
Merge branch 'develop' into deprecate-langspec
ahangsu Aug 22, 2022
9a9da40
detailed deprecation msg
ahangsu Aug 22, 2022
0133232
Merge branch 'develop' into deprecate-langspec
ahangsu Aug 23, 2022
c703e26
add empty program check
ahangsu Aug 24, 2022
faee071
Update logic/logic.go
ahangsu Aug 25, 2022
f0b153f
deprecation msg modify
ahangsu Aug 25, 2022
0c21ff3
more specific error checking santence
ahangsu Aug 25, 2022
a0021b6
move sanity check prog into logicsig def
ahangsu Aug 25, 2022
2329b0e
deprecate MakeLogicSigAccountEscrow for not applying sanity check
ahangsu Aug 25, 2022
6884c74
complete codepath calling makelogicsig
ahangsu Aug 25, 2022
16746ac
Update .test-env
ahangsu Aug 25, 2022
7c40592
oops
ahangsu Aug 25, 2022
a8a7b34
Merge branch 'deprecate-langspec' of github.com:algorand/go-algorand-…
ahangsu Aug 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions crypto/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ type LogicSigAccount struct {

// MakeLogicSigAccountEscrow creates a new escrow LogicSigAccount. The address
// of this account will be a hash of its program.
// Deprecated: This method is deprecated for not applying basic sanity check over program bytes,
// use `MakeLogicSigAccountEscrowChecked` instead.
func MakeLogicSigAccountEscrow(program []byte, args [][]byte) LogicSigAccount {
return LogicSigAccount{
Lsig: types.LogicSig{
Expand All @@ -198,6 +200,16 @@ func MakeLogicSigAccountEscrow(program []byte, args [][]byte) LogicSigAccount {
}
}

// MakeLogicSigAccountEscrowChecked creates a new escrow LogicSigAccount.
// The address of this account will be a hash of its program.
func MakeLogicSigAccountEscrowChecked(program []byte, args [][]byte) (LogicSigAccount, error) {
lsig, err := MakeLogicSig(program, args, nil, MultisigAccount{})
if err != nil {
return LogicSigAccount{}, err
}
return LogicSigAccount{Lsig: lsig}, nil
}

// MakeLogicSigAccountDelegated creates a new delegated LogicSigAccount. This
// type of LogicSig has the authority to sign transactions on behalf of another
// account, called the delegating account. If the delegating account is a
Expand Down
50 changes: 40 additions & 10 deletions crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"crypto/rand"
"crypto/sha512"
"encoding/base32"
"encoding/base64"
"encoding/binary"
"fmt"

"golang.org/x/crypto/ed25519"

"github.com/algorand/go-algorand-sdk/encoding/msgpack"
"github.com/algorand/go-algorand-sdk/logic"
"github.com/algorand/go-algorand-sdk/types"
)

Expand Down Expand Up @@ -160,7 +160,7 @@ func SignBytes(sk ed25519.PrivateKey, bytesToSign []byte) (signature []byte, err
return
}

//VerifyBytes verifies that the signature is valid
// VerifyBytes verifies that the signature is valid
func VerifyBytes(pk ed25519.PublicKey, message, signature []byte) bool {
msgParts := [][]byte{bytesPrefix, message}
toBeVerified := bytes.Join(msgParts, nil)
Expand Down Expand Up @@ -454,6 +454,39 @@ func ComputeGroupID(txgroup []types.Transaction) (gid types.Digest, err error) {

/* LogicSig support */

func isAsciiPrintableByte(symbol byte) bool {
isBreakLine := symbol == '\n'
isStdPrintable := symbol >= ' ' && symbol <= '~'
return isBreakLine || isStdPrintable
}

func isAsciiPrintable(program []byte) bool {
for _, b := range program {
if !isAsciiPrintableByte(b) {
return false
}
}
return true
}

// sanityCheckProgram performs heuristic program validation:
// check if passed in bytes are Algorand address or is B64 encoded, rather than Teal bytes
func sanityCheckProgram(program []byte) error {
if len(program) == 0 {
return fmt.Errorf("empty program")
}
if isAsciiPrintable(program) {
if _, err := types.DecodeAddress(string(program)); err == nil {
return fmt.Errorf("requesting program bytes, get Algorand address")
}
if _, err := base64.StdEncoding.DecodeString(string(program)); err == nil {
return fmt.Errorf("program should not be b64 encoded")
}
return fmt.Errorf("program bytes are all ASCII printable characters, not looking like Teal byte code")
}
return nil
}

// VerifyLogicSig verifies that a LogicSig contains a valid program and, if a
// delegated signature is present, that the signature is valid.
//
Expand All @@ -462,7 +495,7 @@ func ComputeGroupID(txgroup []types.Transaction) (gid types.Digest, err error) {
// multsig account). In that case, it should be the address of the delegating
// account.
func VerifyLogicSig(lsig types.LogicSig, singleSigner types.Address) (result bool) {
if err := logic.CheckProgram(lsig.Logic, lsig.Args); err != nil {
if err := sanityCheckProgram(lsig.Logic); err != nil {
return false
}

Expand Down Expand Up @@ -602,20 +635,17 @@ func AddressFromProgram(program []byte) types.Address {

// MakeLogicSig produces a new LogicSig signature.
//
// THIS FUNCTION IS DEPRECATED. It will be removed in v2 of this library. Use
// one of MakeLogicSigAccountEscrow, MakeLogicSigAccountDelegated, or
// Deprecated: THIS FUNCTION IS DEPRECATED.
// It will be removed in v2 of this library.
// Use one of MakeLogicSigAccountEscrow, MakeLogicSigAccountDelegated, or
// MakeLogicSigAccountDelegatedMsig instead.
//
// The function can work in three modes:
// 1. If no sk and ma provided then it returns contract-only LogicSig
// 2. If no ma provides, it returns Sig delegated LogicSig
// 3. If both sk and ma specified the function returns Multisig delegated LogicSig
func MakeLogicSig(program []byte, args [][]byte, sk ed25519.PrivateKey, ma MultisigAccount) (lsig types.LogicSig, err error) {
Comment thread
jasonpaulos marked this conversation as resolved.
if len(program) == 0 {
err = errLsigInvalidProgram
return
}
if err = logic.CheckProgram(program, args); err != nil {
if err = sanityCheckProgram(program); err != nil {
return
}

Expand Down
7 changes: 0 additions & 7 deletions crypto/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,6 @@ func TestMakeLogicSigBasic(t *testing.T) {
err = msgpack.Decode(encoded, &lsig1)
require.NoError(t, err)
require.Equal(t, lsig, lsig1)

// check invalid program fails
programMod := make([]byte, len(program))
copy(programMod[:], program)
programMod[0] = 128
lsig, err = MakeLogicSig(programMod, args, sk, pk)
require.Error(t, err)
}

func TestMakeLogicSigSingle(t *testing.T) {
Expand Down
13 changes: 13 additions & 0 deletions logic/logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
"github.com/algorand/go-algorand-sdk/types"
)

// Deprecated
type langSpec struct {
EvalMaxVersion int
LogicSigVersion int
Ops []operation
}

// Deprecated
type operation struct {
Opcode int
Name string
Expand All @@ -29,16 +31,23 @@ type operation struct {
Group []string
}

// Deprecated
Comment thread
ahangsu marked this conversation as resolved.
var spec *langSpec

// Deprecated
var opcodes []operation

// CheckProgram performs basic program validation: instruction count and program cost
// Deprecated: Validation relies on metadata (`langspec.json`) that does not accurately represent opcode behavior across program versions.
// The behavior of `CheckProgram` relies on `langspec.json`. Thus, this method is being deprecated.
func CheckProgram(program []byte, args [][]byte) error {
_, _, err := ReadProgram(program, args)
return err
}

// ReadProgram is used to validate a program as well as extract found variables
// Deprecated: Validation relies on metadata (`langspec.json`) that does not accurately represent opcode behavior across program versions.
// The behavior of `ReadProgram` relies on `langspec.json`. Thus, this method is being deprecated.
func ReadProgram(program []byte, args [][]byte) (ints []uint64, byteArrays [][]byte, err error) {
const intcblockOpcode = 32
const bytecblockOpcode = 38
Expand Down Expand Up @@ -138,6 +147,7 @@ func ReadProgram(program []byte, args [][]byte) (ints []uint64, byteArrays [][]b
return
}

// Deprecated
func readIntConstBlock(program []byte, pc int) (size int, ints []uint64, err error) {
size = 1
numInts, bytesUsed := binary.Uvarint(program[pc+size:])
Expand All @@ -163,6 +173,7 @@ func readIntConstBlock(program []byte, pc int) (size int, ints []uint64, err err
return
}

// Deprecated
func readByteConstBlock(program []byte, pc int) (size int, byteArrays [][]byte, err error) {
size = 1
numInts, bytesUsed := binary.Uvarint(program[pc+size:])
Expand Down Expand Up @@ -195,6 +206,7 @@ func readByteConstBlock(program []byte, pc int) (size int, byteArrays [][]byte,
return
}

// Deprecated
func readPushIntOp(program []byte, pc int) (size int, foundInt uint64, err error) {
size = 1
foundInt, bytesUsed := binary.Uvarint(program[pc+size:])
Expand All @@ -207,6 +219,7 @@ func readPushIntOp(program []byte, pc int) (size int, foundInt uint64, err error
return
}

// Deprecated
func readPushByteOp(program []byte, pc int) (size int, byteArray []byte, err error) {
size = 1
itemLen, bytesUsed := binary.Uvarint(program[pc+size:])
Expand Down
34 changes: 33 additions & 1 deletion test/steps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ var txTrace future.DryrunTxnResult
var trace string
var sourceMap logic.SourceMap
var srcMapping map[string]interface{}
var seeminglyProgram []byte
var sanityCheckError error

var assetTestFixture struct {
Creator string
Expand Down Expand Up @@ -387,7 +389,10 @@ func FeatureContext(s *godog.Suite) {
s.Step(`^the resulting source map is the same as the json "([^"]*)"$`, theResultingSourceMapIsTheSameAsTheJson)
s.Step(`^getting the line associated with a pc "([^"]*)" equals "([^"]*)"$`, gettingTheLineAssociatedWithAPcEquals)
s.Step(`^getting the last pc associated with a line "([^"]*)" equals "([^"]*)"$`, gettingTheLastPcAssociatedWithALineEquals)

s.Step(`^a base64 encoded program bytes for heuristic sanity check "([^"]*)"$`, takeB64encodedBytes)
s.Step(`^I start heuristic sanity check over the bytes$`, heuristicCheckOverBytes)
s.Step(`^if the heuristic sanity check throws an error, the error contains "([^"]*)"$`, checkErrorIfMatching)

s.BeforeScenario(func(interface{}) {
stxObj = types.SignedTxn{}
abiMethods = nil
Expand Down Expand Up @@ -2634,3 +2639,30 @@ func theResultingSourceMapIsTheSameAsTheJson(expectedJsonPath string) error {

return nil
}

func takeB64encodedBytes(b64encodedBytes string) error {
var err error
seeminglyProgram, err = base64.StdEncoding.DecodeString(b64encodedBytes)
if err != nil {
return err
}
return nil
}

func heuristicCheckOverBytes() error {
_, sanityCheckError = crypto.MakeLogicSigAccountEscrowChecked(seeminglyProgram, nil)
return nil
}

func checkErrorIfMatching(errMsg string) error {
if len(errMsg) == 0 {
if sanityCheckError != nil {
return fmt.Errorf("expected err message to be empty, but sanity check says %w", sanityCheckError)
}
} else {
if sanityCheckError == nil || !strings.Contains(sanityCheckError.Error(), errMsg) {
return fmt.Errorf("expected err to contain %s, but sanity check error not matching: %w", errMsg, sanityCheckError)
}
}
return nil
}
1 change: 1 addition & 0 deletions test/unit.tags
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@unit.indexer.logs
@unit.indexer.rekey
@unit.offline
@unit.program_sanity_check
@unit.rekey
@unit.responses
@unit.responses.231
Expand Down