Skip to content

Commit

Permalink
Merge bech32m functions into TWBech32 struct
Browse files Browse the repository at this point in the history
  • Loading branch information
10gic committed Nov 8, 2024
1 parent b707e82 commit d134eff
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 238 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,39 @@ class TestBech32 {

@Test
fun testEncode() {
val data = Numeric.hexStringToByteArray("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
val data = Numeric.hexStringToByteArray("00443214c74254b635cf84653a56d7c675be77df")
assertEquals(Bech32.encode("abcdef", data), "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
}

@Test
fun testDecode() {
val decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
assertEquals(Numeric.toHexString(decoded), "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
assertEquals(Numeric.toHexString(decoded), "0x00443214c74254b635cf84653a56d7c675be77df")
}

@Test
fun testDecodeWrongChecksumVariant() {
// This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder.
val decoded = Bech32.decode("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
assertNull(decoded)
}

@Test
fun testEncodeM() {
val data = Numeric.hexStringToByteArray("ffbbcdeb38bdab49ca307b9ac5a928398a418820")
assertEquals(Bech32.encodeM("abcdef", data), "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
}

@Test
fun testDecodeM() {
val decoded = Bech32.decodeM("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
assertEquals(Numeric.toHexString(decoded), "0xffbbcdeb38bdab49ca307b9ac5a928398a418820")
}

@Test
fun testDecodeMWrongChecksumVariant() {
// This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder.
val decoded = Bech32.decodeM("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
assertNull(decoded)
}
}

This file was deleted.

36 changes: 36 additions & 0 deletions codegen-v2/manifest/TWBech32.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,39 @@ functions:
is_constant: true
is_nullable: true
is_pointer: true
- name: TWBech32EncodeM
is_public: true
is_static: true
params:
- name: hrp
type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
- name: data
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
- name: TWBech32DecodeM
is_public: true
is_static: true
params:
- name: string
type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
return_type:
variant: data
is_constant: true
is_nullable: true
is_pointer: true
42 changes: 0 additions & 42 deletions codegen-v2/manifest/TWBech32m.yaml

This file was deleted.

4 changes: 2 additions & 2 deletions include/TrustWalletCore/TWBase58.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ TWString *_Nonnull TWBase58EncodeNoCheck(TWData *_Nonnull data);
/// Decodes a Base58 string, checking the checksum. Returns null if the string is not a valid Base58 string.
///
/// \param string The Base58 string to decode.
/// \return the decoded data, empty if the string is not a valid Base58 string with checksum.
/// \return the decoded data, null if the string is not a valid Base58 string with checksum.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBase58Decode(TWString *_Nonnull string);

/// Decodes a Base58 string, w/o checking the checksum. Returns null if the string is not a valid Base58 string.
///
/// \param string The Base58 string to decode.
/// \return the decoded data, empty if the string is not a valid Base58 string without checksum.
/// \return the decoded data, null if the string is not a valid Base58 string without checksum.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBase58DecodeNoCheck(TWString *_Nonnull string);

Expand Down
17 changes: 16 additions & 1 deletion include/TrustWalletCore/TWBech32.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,23 @@ TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data)
/// Decodes a Bech32 string. Returns null if the string is not a valid Bech32 string.
///
/// \param string The Bech32 string to decode.
/// \return the decoded data, empty if the string is not a valid Bech32. Note that the human-readable part is not returned.
/// \return the decoded data, null if the string is not a valid Bech32 string. Note that the human-readable part is not returned.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBech32Decode(TWString *_Nonnull string);

/// Encodes data as a Bech32m string.
///
/// \param hrp The human-readable part.
/// \param data The data part.
/// \return the encoded Bech32m string.
TW_EXPORT_STATIC_METHOD
TWString *_Nonnull TWBech32EncodeM(TWString* _Nonnull hrp, TWData *_Nonnull data);

/// Decodes a Bech32m string. Returns null if the string is not a valid Bech32m string.
///
/// \param string The Bech32m string to decode.
/// \return the decoded data, null if the string is not a valid Bech32m string. Note that the human-readable part is not returned.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBech32DecodeM(TWString *_Nonnull string);

TW_EXTERN_C_END
32 changes: 0 additions & 32 deletions include/TrustWalletCore/TWBech32m.h

This file was deleted.

4 changes: 2 additions & 2 deletions src/Bech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Data create_checksum(const std::string& hrp, const Data& values, ChecksumVariant

} // namespace

/** Encode a Bech32 string. */
/** Encode a Bech32 string. Note that the values must each encode 5 bits, normally get from convertBits<8, 5, true> */
std::string encode(const std::string& hrp, const Data& values, ChecksumVariant variant) {
Data checksum = create_checksum(hrp, values, variant);
Data combined = values;
Expand All @@ -116,7 +116,7 @@ std::string encode(const std::string& hrp, const Data& values, ChecksumVariant v
return ret;
}

/** Decode a Bech32 string. */
/** Decode a Bech32 string. Note that the returned values are 5 bits each, you may want to use convertBits<5, 8, false> */
std::tuple<std::string, Data, ChecksumVariant> decode(const std::string& str) {
if (str.length() > 120 || str.length() < 2) {
// too long or too short
Expand Down
44 changes: 35 additions & 9 deletions src/interface/TWBech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,51 @@

using namespace TW;

TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data) {
auto cppHrp = *reinterpret_cast<const std::string*>(hrp);
auto cppData = *reinterpret_cast<const Data*>(data);
auto result = Bech32::encode(cppHrp, cppData, Bech32::ChecksumVariant::Bech32);
static TWString *_Nonnull encodeGeneric(TWString* _Nonnull hrp, TWData *_Nonnull data, const Bech32::ChecksumVariant variant) {
const auto cppHrp = *static_cast<const std::string*>(hrp);
const auto cppData = *static_cast<const Data*>(data);
Data enc;
if (!Bech32::convertBits<8, 5, true>(enc, cppData)) {
return TWStringCreateWithUTF8Bytes("");
}
const auto result = Bech32::encode(cppHrp, enc, variant);
return TWStringCreateWithUTF8Bytes(result.c_str());
}

TWData *_Nullable TWBech32Decode(TWString *_Nonnull string) {
auto cppString = *reinterpret_cast<const std::string*>(string);
static TWData *_Nullable decodeGeneric(TWString *_Nonnull string, const Bech32::ChecksumVariant variant) {
const auto cppString = *static_cast<const std::string*>(string);
const auto decoded = Bech32::decode(cppString);

auto data = std::get<1>(decoded);
const auto data = std::get<1>(decoded);
if (data.empty()) { // Failed to decode
return nullptr;
}

if (std::get<2>(decoded) != Bech32::ChecksumVariant::Bech32) { // Wrong ChecksumVariant
if (std::get<2>(decoded) != variant) { // Wrong ChecksumVariant
return nullptr;
}

// Bech bits conversion
Data conv;
if (!Bech32::convertBits<5, 8, false>(conv, data)) {
return nullptr;
}

return TWDataCreateWithBytes(data.data(), data.size());
return TWDataCreateWithBytes(conv.data(), conv.size());
}

TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data) {
return encodeGeneric(hrp, data, Bech32::ChecksumVariant::Bech32);
}

TWString *_Nonnull TWBech32EncodeM(TWString* _Nonnull hrp, TWData *_Nonnull data) {
return encodeGeneric(hrp, data, Bech32::ChecksumVariant::Bech32M);
}

TWData *_Nullable TWBech32Decode(TWString *_Nonnull string) {
return decodeGeneric(string, Bech32::ChecksumVariant::Bech32);
}

TWData *_Nullable TWBech32DecodeM(TWString *_Nonnull string) {
return decodeGeneric(string, Bech32::ChecksumVariant::Bech32M);
}
34 changes: 0 additions & 34 deletions src/interface/TWBech32m.cpp

This file was deleted.

30 changes: 25 additions & 5 deletions swift/Tests/Bech32Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,36 @@ import WalletCore

class Bech32Tests: XCTestCase {
func testEncode() {
let data = Data(hexString: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")!
let data = Data(hexString: "00443214c74254b635cf84653a56d7c675be77df")!
let encoded = Bech32.encode(hrp: "abcdef", data: data)
XCTAssertEqual(encoded, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
}

func testDecode() {
guard let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") else {
return XCTFail()
}
let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
XCTAssertEqual(decoded.hexString, "00443214c74254b635cf84653a56d7c675be77df")

Check failure on line 17 in swift/Tests/Bech32Tests.swift

View workflow job for this annotation

GitHub Actions / build

value of optional type 'Data?' must be unwrapped to refer to member 'hexString' of wrapped base type 'Data'
}

func testDecodeWrongChecksumVariant() {
// This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder.
let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
XCTAssertNil(decoded)
}

func testEncodeM() {
let data = Data(hexString: "ffbbcdeb38bdab49ca307b9ac5a928398a418820")!
let encoded = Bech32.encodeM(hrp: "abcdef", data: data)
XCTAssertEqual(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
}

func testDecodeM() {
let decoded = Bech32.decodeM(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
XCTAssertEqual(decoded.hexString, "ffbbcdeb38bdab49ca307b9ac5a928398a418820")

Check failure on line 34 in swift/Tests/Bech32Tests.swift

View workflow job for this annotation

GitHub Actions / build

value of optional type 'Data?' must be unwrapped to refer to member 'hexString' of wrapped base type 'Data'
}

XCTAssertEqual(decoded.hexString, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
func testDecodeMWrongChecksumVariant() {
// This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder.
let decoded = Bech32.decodeM(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
XCTAssertNil(decoded)
}
}
Loading

0 comments on commit d134eff

Please sign in to comment.