Skip to content

Commit

Permalink
[Barz] add signature formatting utilities (#3211)
Browse files Browse the repository at this point in the history
* Add getFormattedSignature method

* fix tests
  • Loading branch information
rsrbk authored Jun 9, 2023
1 parent 3a46487 commit a6e147a
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ class TestBarz {
assertEquals(result, "0x85a6290917d1DC2C507Ff2D545Ba5aF13e964Ba1")
}

@Test
fun testGetFormattedSignature() {
val signature = Numeric.hexStringToByteArray("3045022009fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33022100e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b")
val authenticatorData = Numeric.hexStringToByteArray("0x1a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d00000000")
val origin = "https://trustwallet.com"
val result = WCBarz.getFormattedSignature(signature, authenticatorData, origin)
assertEquals(Numeric.toHexString(result), "0x09fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000251a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025222c226f726967696e223a2268747470733a2f2f747275737477616c6c65742e636f6d227d000000000000000000000000000000000000000000000000000000")
}

// https://testnet.bscscan.com/tx/0x43fc13dfdf06bbb09da8ce070953753764f1e43782d0c8b621946d8b45749419
@Test
fun testSignK1TransferAccountDeployed() {
Expand Down
8 changes: 8 additions & 0 deletions include/TrustWalletCore/TWBarz.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@ TWData *_Nonnull TWBarzGetInitCodeFromPublicKey(TWString* _Nonnull factory, TWSt
TW_EXPORT_STATIC_METHOD
TWData *_Nonnull TWBarzGetInitCodeFromAttestationObject(TWString* _Nonnull factory, TWString* _Nonnull attestationObject, TWString* _Nonnull verificationFacet);

/// Converts the original ASN-encoded signature from webauthn to the format accepted by Barz
///
/// \param signature Original signature
/// \param authenticatorData Hex encoded authenticator data
/// \param origin URL of the origin from clientDataJSON
/// \return Bytes of the formatted signature
TW_EXPORT_STATIC_METHOD
TWData *_Nonnull TWBarzGetFormattedSignature(TWData* _Nonnull signature, TWData* _Nonnull authenticatorData, TWString* _Nonnull origin);
TW_EXTERN_C_END
25 changes: 25 additions & 0 deletions src/Ethereum/Barz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "HexCoding.h"
#include <WebAuthn.h>
#include "../proto/Barz.pb.h"
#include "AsnParser.h"

namespace TW::Barz {

Expand Down Expand Up @@ -71,4 +72,28 @@ Data getInitCodeFromAttestationObject(const std::string& factoryAddress, const s
return getInitCodeFromPublicKey(factoryAddress, hexEncoded(publicKey), verificationFacet);
}

Data getFormattedSignature(const Data& signature, const Data& authenticatorData, const std::string& origin) {
const std::string clientDataJSONPre = "{\"type\":\"webauthn.get\",\"challenge\":\"";
const std::string clientDataJSONPost = "\",\"origin\":\"" + origin + "\"}";

const auto parsedSignatureOptional = ASN::AsnParser::ecdsa_signature_from_der(signature);
if (!parsedSignatureOptional.has_value()) {
return Data();
}
const Data parsedSignature = parsedSignatureOptional.value();
const Data rValue = subData(parsedSignature, 0, 32);
const Data sValue = subData(parsedSignature, 32, 64);

auto params = Ethereum::ABI::ParamTuple();
params.addParam(std::make_shared<Ethereum::ABI::ParamUInt256>(uint256_t(hexEncoded(rValue))));
params.addParam(std::make_shared<Ethereum::ABI::ParamUInt256>(uint256_t(hexEncoded(sValue))));
params.addParam(std::make_shared<Ethereum::ABI::ParamByteArray>(authenticatorData));
params.addParam(std::make_shared<Ethereum::ABI::ParamString>(clientDataJSONPre));
params.addParam(std::make_shared<Ethereum::ABI::ParamString>(clientDataJSONPost));

Data encoded;
params.encode(encoded);
return encoded;
}

} // namespace TW::Barz
2 changes: 2 additions & 0 deletions src/Ethereum/Barz.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ namespace TW::Barz {
std::string getCounterfactualAddress(const Proto::ContractAddressInput input);
Data getInitCodeFromPublicKey(const std::string& factoryAddress, const std::string& owner, const std::string& verificationFacet);
Data getInitCodeFromAttestationObject(const std::string& factoryAddress, const std::string& attestationObject, const std::string& verificationFacet);
Data getFormattedSignature(const Data& signature, const Data& authenticatorData, const std::string& origin);

}
9 changes: 9 additions & 0 deletions src/interface/TWBarz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ TWData *_Nonnull TWBarzGetInitCodeFromAttestationObject(TWString* _Nonnull facto
const auto& verificationFacetStr = *reinterpret_cast<const std::string*>(verificationFacet);
const auto initCode = TW::Barz::getInitCodeFromAttestationObject(factoryStr, attestationObjectStr, verificationFacetStr);
return TWDataCreateWithData(&initCode);
}

TWData *_Nonnull TWBarzGetFormattedSignature(TWData* _Nonnull signature, TWData* _Nonnull authenticatorData, TWString* _Nonnull origin) {
const auto& signatureData = *reinterpret_cast<const TW::Data*>(signature);
const auto& authenticatorDataConverted = *reinterpret_cast<const TW::Data*>(authenticatorData);
const auto& originStr = *reinterpret_cast<const std::string*>(origin);

const auto initCode = TW::Barz::getFormattedSignature(signatureData, authenticatorDataConverted, originStr);
return TWDataCreateWithData(&initCode);
}
8 changes: 8 additions & 0 deletions swift/Tests/BarzTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ class BarzTests: XCTestCase {
XCTAssertEqual(Barz.getCounterfactualAddress(input: try! input.serializedData()), "0x85a6290917d1DC2C507Ff2D545Ba5aF13e964Ba1");
}

func testFormatSignature() {
let signature = Data(hexString: "0x3045022009fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33022100e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b")!
let authenticatorData = Data(hexString: "0x1a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d00000000")!
let origin = "https://trustwallet.com"
let result = Barz.getFormattedSignature(signature: signature, authenticatorData: authenticatorData, origin: origin);
XCTAssertEqual(result.hexString, "09fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000251a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025222c226f726967696e223a2268747470733a2f2f747275737477616c6c65742e636f6d227d000000000000000000000000000000000000000000000000000000")
}

// https://testnet.bscscan.com/tx/0x43fc13dfdf06bbb09da8ce070953753764f1e43782d0c8b621946d8b45749419
func testSignK1TransferAccountDeployed() {
let input = EthereumSigningInput.with {
Expand Down
26 changes: 24 additions & 2 deletions tests/chains/Ethereum/BarzTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,29 @@ TEST(Barz, GetCounterfactualAddressFromAttestationObject) {
}
}

TEST(Barz, GetFormattedSignature) {
// C++
{
const std::string& signature = "0x3045022009fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33022100e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b";
const std::string& authenticatorData = "0x1a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d00000000";
const std::string& origin = "https://trustwallet.com";

const auto& formattedSignature = Barz::getFormattedSignature(parse_hex(signature), parse_hex(authenticatorData), origin);
ASSERT_EQ(hexEncoded(formattedSignature), "0x09fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000251a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025222c226f726967696e223a2268747470733a2f2f747275737477616c6c65742e636f6d227d000000000000000000000000000000000000000000000000000000");
}

// C
{
const auto signature = DATA("0x3045022009fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33022100e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b");
const auto authenticatorData = DATA("0x1a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d00000000");
const auto origin = STRING("https://trustwallet.com");

const auto& formattedSignatureData = TWBarzGetFormattedSignature(signature.get(), authenticatorData.get(), origin.get());
const auto& formattedSignature = hexEncoded(*reinterpret_cast<const Data*>(WRAPD(formattedSignatureData).get()));
EXPECT_EQ(formattedSignature, "0x09fa8e18a42d76198e072dce79f5b621a24806e2fc4d99c59cc745ad2291fe33e3de1bd5b3264424ecb55a61daf54475d8f86bc24d16b799a3910f9c3ea3593b00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000251a70842af8c1feb7133b81e6a160a6a2be45ee057f0eb6d3f7f5126daa202e071d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025222c226f726967696e223a2268747470733a2f2f747275737477616c6c65742e636f6d227d000000000000000000000000000000000000000000000000000000");
}
}

// https://testnet.bscscan.com/tx/0x43fc13dfdf06bbb09da8ce070953753764f1e43782d0c8b621946d8b45749419
TEST(Barz, SignK1TransferAccountDeployed) {
TW::Ethereum::Proto::SigningInput input;
Expand Down Expand Up @@ -225,5 +248,4 @@ TEST(Barz, SignR1TransferAccountNotDeployed) {
ASSERT_EQ(std::string(output.encoded()), expected);
}
}

}
}

0 comments on commit a6e147a

Please sign in to comment.