1
// Copyright © 2017-2020 Trust Wallet.
2
//
3
// This file is part of Trust. The full Trust copyright notice, including
4
// terms governing use, modification, and redistribution, is contained in the
5
// file LICENSE at the root of the source code distribution tree.
6

7
#include "Bech32Address.h"
8
#include "Bech32.h"
9
#include "Data.h"
10
#include <TrezorCrypto/ecdsa.h>
11

12
using namespace TW;
13

14 1
bool Bech32Address::isValid(const std::string& addr) {
15 1
    return isValid(addr, "");
16
}
17

18 1
bool Bech32Address::isValid(const std::string& addr, const std::string& hrp) {
19 1
    auto dec = Bech32::decode(addr);
20
    // check hrp prefix (if given)
21 1
    if (hrp.length() > 0 && dec.first.compare(0, hrp.length(), hrp) != 0) {
22 1
        return false;
23
    }
24 1
    if (dec.second.empty()) {
25 1
        return false;
26
    }
27

28 1
    Data conv;
29 1
    auto success = Bech32::convertBits<5, 8, false>(conv, dec.second);
30 1
    if (!success || conv.size() < 2 || conv.size() > 40) {
31 0
        return false;
32
    }
33

34 1
    return true;
35
}
36

37 1
bool Bech32Address::decode(const std::string& addr, Bech32Address& obj_out, const std::string& hrp) {
38 1
    auto dec = Bech32::decode(addr);
39
    // check hrp prefix (if given)
40 1
    if (hrp.length() > 0 && dec.first.compare(0, hrp.length(), hrp) != 0) {
41 1
        return false;
42
    }
43 1
    if (dec.second.empty()) {
44 0
        return false;
45
    }
46

47 1
    Data conv;
48 1
    auto success = Bech32::convertBits<5, 8, false>(conv, dec.second);
49 1
    if (!success || conv.size() < 2 || conv.size() > 40) {
50 0
        return false;
51
    }
52

53 1
    obj_out.setHrp(dec.first);
54 1
    obj_out.setKey(conv);
55 1
    return true;
56
}
57

58 1
Bech32Address::Bech32Address(const std::string& hrp, HasherType hasher, const PublicKey& publicKey)
59 1
: hrp(hrp) {
60 1
    switch (hasher) {
61
        case HASHER_SHA2_RIPEMD:
62
            {
63 1
                auto key = Data(20);
64 1
                ecdsa_get_pubkeyhash(publicKey.compressed().bytes.data(), HASHER_SHA2_RIPEMD, key.data());
65 1
                setKey(key);
66
            }
67 1
            break;
68
        
69
        case HASHER_SHA2:
70
            {
71 1
                const auto hash = Hash::sha256(publicKey.bytes);
72 1
                auto key = Data(20);
73 1
                std::copy(hash.end() - 20, hash.end(), key.begin());
74 1
                setKey(key);
75
            }
76 1
            break;
77

78
        case HASHER_SHA3K:
79
            {
80 1
                const auto hash = publicKey.hash({}, static_cast<Hash::HasherSimpleType>(Hash::keccak256), true);
81 1
                auto key = Data(20);
82 1
                std::copy(hash.end() - 20, hash.end(), key.begin());
83 1
                setKey(key);
84
            }
85 1
            break;
86

87
        default:
88 0
            throw std::invalid_argument("Invalid HasherType in Bech32Address");
89
    }
90
}
91

92 1
std::string Bech32Address::string() const {
93 1
    Data enc;
94 1
    if (!Bech32::convertBits<8, 5, true>(enc, keyHash)) {
95 0
        return "";
96
    }
97 1
    std::string result = Bech32::encode(hrp, enc);
98
    // check back
99 1
    Bech32Address obj;
100 1
    if (!decode(result, obj, hrp)) {
101 0
        return "";
102
    }
103 1
    return result;
104
}

Read our documentation on viewing source code .

Loading