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

8
#include "SegwitAddress.h"
9
#include "../Bech32.h"
10

11
#include <TrezorCrypto/ecdsa.h>
12
#include <TrustWalletCore/TWHRP.h>
13

14
using namespace TW::Bitcoin;
15

16 1
bool SegwitAddress::isValid(const std::string& string) {
17 1
    auto dec = Bech32::decode(string);
18 1
    if (dec.second.empty()) {
19 1
        return false;
20
    }
21

22 1
    Data conv;
23 1
    if (!Bech32::convertBits<5, 8, false>(conv, Data(dec.second.begin() + 1, dec.second.end())) ||
24 1
        conv.size() < 2 || conv.size() > 40 || dec.second[0] > 16 ||
25 1
        (dec.second[0] == 0 && conv.size() != 20 && conv.size() != 32)) {
26 0
        return false;
27
    }
28

29 1
    return true;
30
}
31

32 1
bool SegwitAddress::isValid(const std::string& string, const std::string& hrp) {
33 1
    auto dec = Bech32::decode(string);
34 1
    if (dec.second.empty()) {
35 1
        return false;
36
    }
37 1
    if (dec.first != hrp) {
38 1
        return false;
39
    }
40

41 1
    Data conv;
42 1
    if (!Bech32::convertBits<5, 8, false>(conv, Data(dec.second.begin() + 1, dec.second.end())) ||
43 1
        conv.size() < 2 || conv.size() > 40 || dec.second[0] > 16 ||
44 1
        (dec.second[0] == 0 && conv.size() != 20 && conv.size() != 32)) {
45 0
        return false;
46
    }
47

48 1
    return true;
49
}
50

51 1
SegwitAddress::SegwitAddress(const PublicKey& publicKey, int witver, std::string hrp)
52 1
    : hrp(std::move(hrp)), witnessVersion(witver), witnessProgram() {
53 1
    if (publicKey.type != TWPublicKeyTypeSECP256k1) {
54 0
        throw std::invalid_argument("SegwitAddress needs a compressed SECP256k1 public key.");
55
    }
56 1
    witnessProgram.resize(20);
57 1
    ecdsa_get_pubkeyhash(publicKey.compressed().bytes.data(), HASHER_SHA2_RIPEMD,
58 1
                         witnessProgram.data());
59
}
60

61 1
std::pair<SegwitAddress, bool> SegwitAddress::decode(const std::string& addr) {
62 1
    auto dec = Bech32::decode(addr);
63 1
    if (dec.second.empty()) {
64 1
        return std::make_pair(SegwitAddress(), false);
65
    }
66

67 1
    Data conv;
68 1
    if (!Bech32::convertBits<5, 8, false>(conv, Data(dec.second.begin() + 1, dec.second.end())) ||
69 1
        conv.size() < 2 || conv.size() > 40 || dec.second[0] > 16 ||
70 1
        (dec.second[0] == 0 && conv.size() != 20 && conv.size() != 32)) {
71 1
        return std::make_pair(SegwitAddress(), false);
72
    }
73

74 1
    return std::make_pair(SegwitAddress(dec.first, dec.second[0], conv), true);
75
}
76

77 1
std::string SegwitAddress::string() const {
78 1
    Data enc;
79 1
    enc.push_back(static_cast<uint8_t>(witnessVersion));
80 1
    Bech32::convertBits<8, 5, true>(enc, witnessProgram);
81 1
    std::string result = Bech32::encode(hrp, enc);
82 1
    if (!decode(result).second) {
83 1
        return {};
84
    }
85 1
    return result;
86
}
87

88 0
std::pair<SegwitAddress, bool> SegwitAddress::fromRaw(const std::string& hrp,
89
                                                      const std::vector<uint8_t>& data) {
90 0
    Data conv;
91 0
    if (!Bech32::convertBits<5, 8, false>(conv, Data(data.begin() + 1, data.end())) ||
92 0
        conv.size() < 2 || conv.size() > 40 || data[0] > 16 ||
93 0
        (data[0] == 0 && conv.size() != 20 && conv.size() != 32)) {
94 0
        return std::make_pair(SegwitAddress(), false);
95
    }
96

97 0
    return std::make_pair(SegwitAddress(hrp, data[0], conv), true);
98
}

Read our documentation on viewing source code .

Loading