public void ValidateTransactionSignature_will_pass_with_valid_transaction_signature() { var subbedLogger = Substitute.For <ILogger>(); var cryptoContext = new FfiWrapper(); var transactionValidator = new TransactionValidator(subbedLogger, cryptoContext); // build a valid transaction var privateKey = cryptoContext.GeneratePrivateKey(); var validTransaction = new PublicEntry { SenderAddress = privateKey.GetPublicKey().Bytes.ToByteString() }; var signingContext = new SigningContext { NetworkType = NetworkType.Devnet, SignatureType = SignatureType.TransactionPublic }; var signature = new Signature { // sign an actual TransactionBroadcast object RawBytes = cryptoContext.Sign(privateKey, validTransaction.ToByteArray(), signingContext.ToByteArray()) .SignatureBytes.ToByteString(), SigningContext = signingContext }; validTransaction.Signature = signature; var result = transactionValidator.ValidateTransaction(validTransaction); result.Should().BeTrue(); }
private byte[] PrepareEd25519PrecompileCall(HashProvider hashProvider, FfiWrapper cryptoContext, IPrivateKey signingPrivateKey, IPrivateKey otherPrivateKey) { var data = Encoding.UTF8.GetBytes("Testing testing 1 2 3"); var message = hashProvider.ComputeMultiHash(data).Digest; var signingContext = Encoding.UTF8.GetBytes("Testing testing 1 2 3 context"); var context = hashProvider.ComputeMultiHash(signingContext).Digest; ISignature signature = cryptoContext.Sign(signingPrivateKey, message, context); var signatureBytes = signature.SignatureBytes; var publicKeyBytes = otherPrivateKey.GetPublicKey().Bytes; // below verify check is not needed but allows for greater confidence for any person in the future // that would approach and debug test when it goes wrong // ===================================================== cryptoContext.Verify(signature, message, context) .Should().BeTrue("signature generated with private key should verify with corresponding public key"); // ===================================================== // save message hash in memory at position 0x00 string pushToMemoryAt0 = "7f" + message.ToHexString(false) + "600052"; // save first 32 bytes of the sig in memory starting from position 0x20 string pushToMemoryAt32 = "7f" + signatureBytes.AsSpan(0, 32).ToHexString(false) + "602052"; // save remaining 32 bytes of the sig in memory starting from position 0x40 string pushToMemoryAt64 = "7f" + signatureBytes.AsSpan(32, 32).ToHexString(false) + "604052"; // save context bytes in memory starting from position 0x60 (but this should be changed if context is smaller) string pushToMemoryAt96 = "7f" + context.ToHexString(false) + "606052"; // save public key bytes in memory starting from position 0x80 (but this should be changed if context is smaller) string pushToMemoryAt128 = "7f" + publicKeyBytes.ToHexString(false) + "608052"; // address of the precompile within Catalyst string addressCode = GetEd25519PrecompileAddressAsHex(); var byteCode = Bytes.FromHexString( pushToMemoryAt0 + pushToMemoryAt32 + pushToMemoryAt64 + pushToMemoryAt96 + pushToMemoryAt128 + // PUSH1 32 PUSH1 0 PUSH1 160 PUSH1 0 PUSH20 address GAS STATICCALL // make a call to precompile and pass [0,160) bytes of memory as an input // and store result at [0,1) of memory array // allow precompile to use all the gas required "6001600060a0600073" + addressCode + "45fa00"); TestContext.WriteLine(byteCode.ToHexString()); return(byteCode); }