-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Webauthn public key support * Update Webauthn.h * Update Webauthn.cpp * Code review fixes * make public key optional * rename files * Counterfactual address computation for ERC-4337 (#3150) Added to your initial branch you can follow up the fixes in the other branch * Move Barz to separate files * update tests * update tests * Update EIP4337Tests.cpp * Update TWEthereum.cpp * Update TestBarz.kt * Update TWEthereum.cpp * Create TWBarz.yaml * Update WalletCore.h * Update TestBarz.kt * Update TestBarz.kt * Update TestBarz.kt * Update TWBarz.yaml * feat(barz): fix barz --------- Co-authored-by: Milerius <[email protected]>
- Loading branch information
Showing
13 changed files
with
525 additions
and
0 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: TWBarz | ||
structs: | ||
- name: TWBarz | ||
is_public: true | ||
is_class: false | ||
functions: | ||
- name: TWBarzGetCounterfactualAddress | ||
is_public: true | ||
is_static: true | ||
params: | ||
- name: input | ||
type: | ||
variant: data | ||
is_constant: true | ||
is_nullable: false | ||
is_pointer: true | ||
return_type: | ||
variant: string | ||
is_constant: true | ||
is_nullable: false | ||
is_pointer: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
#pragma once | ||
|
||
#include "TWBase.h" | ||
#include "TWData.h" | ||
#include "TWString.h" | ||
|
||
TW_EXTERN_C_BEGIN | ||
|
||
/// Barz functions | ||
TW_EXPORT_STRUCT | ||
struct TWBarz; | ||
|
||
/// Calculate a counterfactual address for the smart contract wallet | ||
/// | ||
/// \param input The serialized data of ContractAddressInput. | ||
/// \return The address. | ||
TW_EXPORT_STATIC_METHOD | ||
TWString *_Nonnull TWBarzGetCounterfactualAddress(TWData *_Nonnull input); | ||
|
||
TW_EXTERN_C_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
|
||
#include "ABI.h" | ||
#include "AddressChecksum.h" | ||
#include "EIP1014.h" | ||
#include "Hash.h" | ||
#include "HexCoding.h" | ||
#include <WebAuthn.h> | ||
#include "../proto/Barz.pb.h" | ||
|
||
namespace TW::Barz { | ||
|
||
using ParamBasePtr = std::shared_ptr<TW::Ethereum::ABI::ParamBase>; | ||
using ParamCollection = std::vector<ParamBasePtr>; | ||
|
||
std::string getCounterfactualAddress(const TW::Barz::Proto::ContractAddressInput input) { | ||
auto params = TW::Ethereum::ABI::ParamTuple(); | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamAddress>(parse_hex(input.diamond_cut_facet()))); | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamAddress>(parse_hex(input.account_facet()))); | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamAddress>(parse_hex(input.verification_facet()))); | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamAddress>(parse_hex(input.entry_point()))); | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamAddress>(parse_hex(input.security_manager()))); | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamAddress>(parse_hex(input.facet_registry()))); | ||
|
||
Data publicKey; | ||
switch (input.owner().kind_case()) { | ||
case TW::Barz::Proto::ContractOwner::KindCase::KIND_NOT_SET: | ||
return ""; | ||
case TW::Barz::Proto::ContractOwner::KindCase::kPublicKey: | ||
publicKey = parse_hex(input.owner().public_key()); | ||
break; | ||
case TW::Barz::Proto::ContractOwner::KindCase::kAttestationObject: | ||
const auto attestationObject = parse_hex(input.owner().attestation_object()); | ||
publicKey = subData(TW::WebAuthn::getPublicKey(attestationObject)->bytes, 1); // Drop the first byte which corresponds to the public key type | ||
break; | ||
} | ||
params.addParam(std::make_shared<TW::Ethereum::ABI::ParamByteArray>(publicKey)); | ||
|
||
Data encoded; | ||
params.encode(encoded); | ||
|
||
Data initCode = parse_hex(input.bytecode()); | ||
append(initCode, encoded); | ||
|
||
const Data initCodeHash = Hash::keccak256(initCode); | ||
const Data salt(32, 0); | ||
return Ethereum::checksumed(TW::Ethereum::Address(hexEncoded(TW::Ethereum::create2Address(input.factory(), salt, initCodeHash)))); | ||
} | ||
|
||
} // namespace TW::Barz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
|
||
#pragma once | ||
|
||
#include "Data.h" | ||
#include "uint256.h" | ||
#include "../proto/Barz.pb.h" | ||
|
||
namespace TW::Barz { | ||
|
||
std::string getCounterfactualAddress(const TW::Barz::Proto::ContractAddressInput input); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
|
||
|
||
#include "Cbor.h" | ||
#include "PublicKey.h" | ||
|
||
#include <iostream> | ||
#include <utility> | ||
#include <algorithm> | ||
|
||
namespace TW::WebAuthn { | ||
|
||
// https://www.w3.org/TR/webauthn-2/#authenticator-data | ||
struct AuthData { | ||
Data rpIdHash; | ||
std::array<std::uint8_t, 1> flagsBuf; | ||
struct { | ||
bool up; | ||
bool uv; | ||
bool at; | ||
bool ed; | ||
std::uint8_t flagsInt; | ||
} flags; | ||
std::uint32_t counter; | ||
Data counterBuf; | ||
Data aaguid; | ||
Data credID; | ||
Data COSEPublicKey; | ||
}; | ||
|
||
AuthData parseAuthData(const Data& buffer) { | ||
AuthData authData; | ||
|
||
authData.rpIdHash = subData(buffer, 0, 32); | ||
|
||
auto it = buffer.begin() + 32; | ||
authData.flagsBuf = { *it }; | ||
++it; | ||
std::uint8_t flagsInt = authData.flagsBuf[0]; | ||
authData.flags.up = !!(flagsInt & 0x01); | ||
authData.flags.uv = !!(flagsInt & 0x04); | ||
authData.flags.at = !!(flagsInt & 0x40); | ||
authData.flags.ed = !!(flagsInt & 0x80); | ||
authData.flags.flagsInt = flagsInt; | ||
|
||
authData.counterBuf = Data(it, it + 4); | ||
authData.counter = static_cast<std::uint32_t>((authData.counterBuf[0] << 24) | | ||
(authData.counterBuf[1] << 16) | | ||
(authData.counterBuf[2] << 8) | | ||
authData.counterBuf[3]); | ||
it += 4; | ||
|
||
if (authData.flags.at) { | ||
authData.aaguid = Data(it, it + 16); | ||
it += 16; | ||
|
||
std::array<std::uint8_t, 2> credIDLenBuf = { *(it), *(it + 1) }; | ||
std::uint16_t credIDLen = static_cast<std::uint16_t>((credIDLenBuf[0] << 8) | | ||
credIDLenBuf[1]); | ||
it += 2; | ||
|
||
authData.credID = Data(it, it + credIDLen); | ||
it += credIDLen; | ||
|
||
authData.COSEPublicKey = Data(it, buffer.end()); | ||
} | ||
|
||
return authData; | ||
} | ||
|
||
auto findIntKey = [](const auto& map, const auto& key) { | ||
return std::find_if(map.begin(), map.end(), [&](const auto& p) { | ||
return p.first.dumpToString() == key; | ||
}); | ||
}; | ||
|
||
auto findStringKey = [](const auto& map, const auto& key) { | ||
return std::find_if(map.begin(), map.end(), [&](const auto& p) { | ||
return p.first.getString() == key; | ||
}); | ||
}; | ||
|
||
std::optional<PublicKey> getPublicKey(const Data& attestationObject) { | ||
const Data authData = findStringKey(TW::Cbor::Decode(attestationObject).getMapElements(), "authData")->second.getBytes(); | ||
if (authData.empty()) { | ||
return std::nullopt; | ||
} | ||
|
||
const AuthData authDataParsed = parseAuthData(authData); | ||
const auto COSEPublicKey = TW::Cbor::Decode(authDataParsed.COSEPublicKey).getMapElements(); | ||
|
||
if (COSEPublicKey.empty()) { | ||
return std::nullopt; | ||
} | ||
|
||
// https://www.w3.org/TR/webauthn-2/#sctn-encoded-credPubKey-examples | ||
const std::string xKey = "-2"; | ||
const std::string yKey = "-3"; | ||
|
||
const auto x = findIntKey(COSEPublicKey, xKey); | ||
const auto y = findIntKey(COSEPublicKey, yKey); | ||
|
||
Data publicKey; | ||
append(publicKey, 0x04); | ||
append(publicKey, x->second.getBytes()); | ||
append(publicKey, y->second.getBytes()); | ||
|
||
return PublicKey(publicKey, TWPublicKeyTypeNIST256p1Extended); | ||
} | ||
|
||
} // namespace TW::Webauthn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
|
||
#pragma once | ||
|
||
#include "Data.h" | ||
#include "PublicKey.h" | ||
#include <optional> | ||
|
||
namespace TW::WebAuthn { | ||
|
||
std::optional<PublicKey> getPublicKey(const Data& attestationObject); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
|
||
#include <TrustWalletCore/TWBarz.h> | ||
#include <string> | ||
#include "Ethereum/Barz.h" | ||
|
||
TWString *_Nonnull TWBarzGetCounterfactualAddress(TWData *_Nonnull input) { | ||
TW::Barz::Proto::ContractAddressInput inputProto; | ||
|
||
const auto bytes = TWDataBytes(input); | ||
const auto size = static_cast<int>(TWDataSize(input)); | ||
if (!inputProto.ParseFromArray(bytes, size)) { | ||
return ""; | ||
} | ||
|
||
return TWStringCreateWithUTF8Bytes(TW::Barz::getCounterfactualAddress(inputProto).c_str()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright © 2017-2023 Trust Wallet. | ||
// | ||
// This file is part of Trust. The full Trust copyright notice, including | ||
// terms governing use, modification, and redistribution, is contained in the | ||
// file LICENSE at the root of the source code distribution tree. | ||
|
||
syntax = "proto3"; | ||
|
||
package TW.Barz.Proto; | ||
option java_package = "wallet.core.jni.proto"; | ||
|
||
import "Common.proto"; | ||
|
||
// Represents the access control to the wallet | ||
message ContractOwner { | ||
oneof kind { | ||
string public_key = 1; | ||
string attestation_object = 2; | ||
} | ||
} | ||
|
||
// Input parameters for calculating a counterfactual address for ERC-4337 based smart contract wallet | ||
message ContractAddressInput { | ||
// Address of the contract factory | ||
string factory = 1; | ||
|
||
// Diamond proxy facets required for the contract setup | ||
string diamond_cut_facet = 2; | ||
string account_facet = 3; | ||
string verification_facet = 4; | ||
|
||
// ERC-4337 entry point | ||
string entry_point = 5; | ||
|
||
// Address of the contract that defines security constraints | ||
string security_manager = 6; | ||
|
||
// Address of the contract that defines if a facet is secure | ||
string facet_registry = 7; | ||
|
||
// Bytecode of the smart contract to deploy | ||
string bytecode = 8; | ||
|
||
// Owner of the wallet | ||
ContractOwner owner = 9; | ||
} |
Oops, something went wrong.