From f45ab2f25fe44b3ec6c2ea5a139409e731f3b409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Di=20Pietro?= Date: Fri, 19 Nov 2021 16:00:24 -0300 Subject: [PATCH] FIX: Signature verification WORKS. --- teal/wormhole/pyteal/vaa-verify.py | 30 +++++++++++++++++++----------- test/testlib.js | 4 +++- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/teal/wormhole/pyteal/vaa-verify.py b/teal/wormhole/pyteal/vaa-verify.py index e54e32a3..e7a9515f 100644 --- a/teal/wormhole/pyteal/vaa-verify.py +++ b/teal/wormhole/pyteal/vaa-verify.py @@ -31,6 +31,7 @@ SLOTID_RECOVERED_PK_Y = 241 def sig_check(signatures, digest, keys): si = ScratchVar(TealType.uint64) ki = ScratchVar(TealType.uint64) + i = ScratchVar(TealType.uint64) rec_pk_x = ScratchVar(TealType.bytes, SLOTID_RECOVERED_PK_X) rec_pk_y = ScratchVar(TealType.bytes, SLOTID_RECOVERED_PK_Y) @@ -39,34 +40,41 @@ def sig_check(signatures, digest, keys): rec_pk_x.store(Bytes("")), rec_pk_y.store(Bytes("")), For(Seq([ + i.store(Int(0)), si.store(Int(0)), ki.store(Int(0)) ]), si.load() < Len(signatures), Seq([ si.store(si.load() + Int(66)), - ki.store(ki.load() + Int(32)), + ki.store(ki.load() + Int(20)), + i.store(i.load() + Int(1)), ])).Do( Seq([ + # Index must be sequential + + Assert(Btoi(Extract(signatures, si.load(), Int(1))) == + i.load() + (Txn.group_index() * Int(MAX_SIGNATURES_PER_VERIFICATION_STEP))), + InlineAssembly( "ecdsa_pk_recover Secp256k1", - digest, - Btoi(Extract(signatures, si.load() + Int(64), Int(1))), - Extract(signatures, si.load() + Int(32), Int(32)), - Extract(signatures, si.load(), Int(32)), + Keccak256(digest), + Btoi(Extract(signatures, si.load() + Int(65), Int(1))), + Extract(signatures, si.load() + Int(1), Int(32)), # R + Extract(signatures, si.load() + Int(33), Int(32)), # S type=TealType.none), # returned values in stack, pass to scratch-vars - InlineAssembly("store " + str(SLOTID_RECOVERED_PK_X)), InlineAssembly("store " + str(SLOTID_RECOVERED_PK_Y)), + InlineAssembly("store " + str(SLOTID_RECOVERED_PK_X)), # Generate Ethereum-type public key, compare with guardian key. Assert( - Extract(keys, ki.load(), Int(32)) == - Extract(Keccak256(Concat(rec_pk_x.load(), - rec_pk_y.load())), Int(0), Int(20)) + Extract(keys, ki.load(), Int(20)) == + Substring(Keccak256(Concat(rec_pk_x.load(), + rec_pk_y.load())), Int(12), Int(32)) ) ]) @@ -79,7 +87,7 @@ def sig_check(signatures, digest, keys): """ * Let N be the number of signatures per verification step, for the TX(i) in group, we verify signatures [j..k] where j = i*N, k = j+(N-1) -* Input 0 is signatures [j..k] to verify as LogicSigArgs. +* Input 0 is signatures [j..k] to verify as LogicSigArgs. (Format is GuardianIndex + signature) * Input 1 is signed digest of payload, contained in the note field of the TX in current slot. * Input 2 is public keys for guardians [j..k] contained in the first Argument of the TX in current slot. * Input 3 is guardian set size contained in the second argument of the TX in current slot. @@ -94,7 +102,7 @@ def vaa_verify_program(vaa_processor_app_id): return Seq([ Assert(Txn.fee() <= Int(1000)), - Assert(Txn.application_args.length() == Int(1)), + Assert(Txn.application_args.length() == Int(3)), Assert(Len(signatures) == get_sig_count_in_step( Txn.group_index(), Btoi(num_guardians)) * Int(66)), Assert(Txn.rekey_to() == Global.zero_address()), diff --git a/test/testlib.js b/test/testlib.js index 65ed0c28..21d8fa37 100644 --- a/test/testlib.js +++ b/test/testlib.js @@ -43,7 +43,9 @@ class TestLib { payload.substr(2) ] - const hash = web3Utils.soliditySha3(web3Utils.soliditySha3('0x' + body.join(''))) + const hash = web3Utils.keccak256('0x' + body.join('')) + + console.log('VAA body Hash: ', hash) let signatures = ''