@@ -33,6 +33,7 @@ import (
3333 "github.com/algorand/go-algorand/crypto/secp256k1"
3434 "github.com/algorand/go-algorand/data/basics"
3535 "github.com/algorand/go-algorand/data/transactions"
36+ "github.com/algorand/go-algorand/protocol"
3637 "github.com/algorand/go-algorand/test/partitiontest"
3738)
3839
@@ -131,6 +132,155 @@ ed25519verify`, pkStr), v)
131132 }
132133}
133134
135+ func TestEd25519verifyCompatValid (t * testing.T ) {
136+ partitiontest .PartitionTest (t )
137+
138+ // ed25519verify opcode uses prefix "ProgData" || program_hash in hex
139+ // the following snippet produces: "50726f67446174610fefbfeb4749642b4e93f37098946ce11a63d6a8db82a416ff91321760212fac"
140+ // for use below
141+ /*
142+ ops, err := AssembleStringWithVersion(`arg 0
143+ arg 1
144+ arg 2
145+ ed25519verify`, AssemblerMaxVersion)
146+ require.NoError(t, err)
147+ h := crypto.HashObj(Program(ops.Program))
148+ t.Log("program hash", hex.EncodeToString(h[:]))
149+ t.Log("progdata", hex.EncodeToString([]byte(protocol.ProgramData)))
150+ cat := append([]byte(protocol.ProgramData), h[:]...)
151+ t.Log("progdata||program_hash", hex.EncodeToString(cat))
152+ */
153+ // generated by github.com/p-steuer/eddsa-test
154+ data , err := hex .DecodeString ("cb68" )
155+ require .NoError (t , err )
156+ vecs := [][3 ]string {
157+ {
158+ "50726f67446174610fefbfeb4749642b4e93f37098946ce11a63d6a8db82a416ff91321760212faccb68" , // msg M
159+ "5866666666666666666666666666666666666666666666666666666666666666" , // pub A
160+ "01000000000000000000000000000000000000000000000000000000000000006a889c732ac8ea1507a1547dcee1d74efc9113f9377216d8dfacc7fee5156504" , // sig (R,S)
161+ },
162+ }
163+ vecBytes := make ([][3 ][]byte , len (vecs ))
164+ for i , tup3 := range vecs {
165+ for j := range tup3 {
166+ vecBytes [i ][j ], err = hex .DecodeString (vecs [i ][j ])
167+ require .NoError (t , err )
168+ }
169+ }
170+
171+ for i , vec := range vecBytes {
172+ t .Run (fmt .Sprintf ("valid,vec=%v" , vecs [i ]), func (t * testing.T ) {
173+ // simple program that is only valid if EnableBatchVerification=true
174+ ops , err := AssembleStringWithVersion (fmt .Sprintf (`arg 0
175+ arg 1
176+ arg 2
177+ ed25519verify` ), uint64 (6 ))
178+ require .NoError (t , err )
179+ var txn transactions.SignedTxn
180+ txn .Lsig .Logic = ops .Program
181+ txn .Lsig .Args = [][]byte {data [:], vec [2 ], vec [1 ]}
182+ sb := strings.Builder {}
183+
184+ // try with EnableBatchVerification = false
185+ evalParams := defaultEvalParams (& sb , & txn )
186+ evalParams .Proto .EnableBatchVerification = false
187+ pass , err := Eval (ops .Program , evalParams )
188+ require .False (t , pass )
189+ require .NoError (t , err )
190+
191+ // try with EnableBatchVerification = true
192+ evalParams .Proto .EnableBatchVerification = true
193+ pass , err = Eval (ops .Program , evalParams )
194+ require .True (t , pass )
195+ require .NoError (t , err )
196+ })
197+ }
198+ }
199+
200+ func TestEd25519verifyCompatPayment (t * testing.T ) {
201+ partitiontest .PartitionTest (t )
202+
203+ // generated by github.com/p-steuer/eddsa-test
204+ data , err := hex .DecodeString ("1dab" )
205+ require .NoError (t , err )
206+ vecs := [][3 ]string {
207+ {
208+ "50726f6744617461f6691f135f7945d27ec1f87846d0694709e2ae67808ff4082a007a15754cb9a51dab" , // msg M
209+ "5866666666666666666666666666666666666666666666666666666666666666" , // pub A
210+ "0100000000000000000000000000000000000000000000000000000000000000095660bba17daf63dac3dc8c8600c55e25dd077032ff3c050bb0e9cdd0293b0e" , // sig (R,S)
211+ },
212+ }
213+ vecBytes := make ([][3 ][]byte , len (vecs ))
214+ for i , tup3 := range vecs {
215+ for j := range tup3 {
216+ vecBytes [i ][j ], err = hex .DecodeString (vecs [i ][j ])
217+ require .NoError (t , err )
218+ }
219+ }
220+
221+ for i , vec := range vecBytes {
222+ t .Run (fmt .Sprintf ("valid,vec=%v" , vecs [i ]), func (t * testing.T ) {
223+ // logic sig that lets you withdraw different amounts if EnableBatchVerification=true
224+ /* (||
225+ (&& (ed25519verify (arg 0) (arg 1) (arg 2))
226+ (== (txn Amount) 1000000))
227+ (&& (! (ed25519verify (arg 0) (arg 1) (arg 2)))
228+ (== (txn Amount) 2000000))
229+ )
230+ */
231+ ops , err := AssembleStringWithVersion (`arg 0
232+ arg 1
233+ arg 2
234+ ed25519verify
235+ txn Amount
236+ int 1000000
237+ ==
238+ &&
239+ arg 0
240+ arg 1
241+ arg 2
242+ ed25519verify
243+ !
244+ txn Amount
245+ int 2000000
246+ ==
247+ &&
248+ ||` , uint64 (6 ))
249+ require .NoError (t , err )
250+ h := crypto .HashObj (Program (ops .Program ))
251+ t .Log ("program hash" , hex .EncodeToString (h [:]))
252+ t .Log ("progdata" , hex .EncodeToString ([]byte (protocol .ProgramData )))
253+ cat := append ([]byte (protocol .ProgramData ), h [:]... )
254+ t .Log ("progdata||program_hash" , hex .EncodeToString (cat ))
255+
256+ for _ , tc := range []struct {
257+ amount uint64
258+ enableBatchVerification bool
259+ valid bool
260+ }{
261+ {1000000 , false , false }, // EnableBatchVerification = false, can't withdraw 1 algo
262+ {2000000 , false , true }, // EnableBatchVerification = false, withdraw 2 algos
263+ {1000000 , true , true }, // EnableBatchVerification = true, withdraw 1 algo
264+ {2000000 , true , false }, // EnableBatchVerification = true, can't withdraw 2 algos
265+ } {
266+ t .Run (fmt .Sprintf ("%+v" , tc ), func (t * testing.T ) {
267+ var txn transactions.SignedTxn
268+ txn .Lsig .Logic = ops .Program
269+ txn .Lsig .Args = [][]byte {data [:], vec [2 ], vec [1 ]}
270+ sb := strings.Builder {}
271+ txn .Txn .Amount = basics.MicroAlgos {Raw : tc .amount }
272+ evalParams := defaultEvalParams (& sb , & txn )
273+ evalParams .Proto .EnableBatchVerification = tc .enableBatchVerification
274+ pass , err := Eval (ops .Program , evalParams )
275+ require .Equal (t , tc .valid , pass , "trace %s" , sb .String ())
276+ t .Log (sb .String ())
277+ require .NoError (t , err )
278+ })
279+ }
280+ })
281+ }
282+ }
283+
134284// bitIntFillBytes is a replacement for big.Int.FillBytes from future Go
135285func bitIntFillBytes (b * big.Int , buf []byte ) []byte {
136286 for i := range buf {
0 commit comments