From bbb0ee205f18279eda783f8b165ce226761feaf9 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Tue, 7 Jun 2022 14:28:39 -0700 Subject: [PATCH] fix bech32 Signed-off-by: William Casarin --- damus/Util/Bech32.swift | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/damus/Util/Bech32.swift b/damus/Util/Bech32.swift index 6e68c47c..a9b0d4ea 100644 --- a/damus/Util/Bech32.swift +++ b/damus/Util/Bech32.swift @@ -92,6 +92,32 @@ func bech32_checksum(hrp: String, data: [UInt8]) -> [UInt8] { return result.map { UInt8($0) } } +func bech32_convert_bits(outbits: Int, input: Data, inbits: Int, pad: Int) -> Data? { + let maxv: UInt32 = ((UInt32(1)) << outbits) - 1; + var val: UInt32 = 0 + var bits: Int = 0 + var out = Data() + + for i in (0..= outbits { + bits -= outbits; + out.append(UInt8((val >> bits) & maxv)) + } + } + + if pad != 0 { + if bits != 0 { + out.append(UInt8(val << (outbits - bits) & maxv)) + } + } else if 0 != ((val << (outbits - bits)) & maxv) || bits >= inbits { + return nil + } + + return out +} + func eightToFiveBits(_ input: [UInt8]) -> [UInt8] { guard !input.isEmpty else { return [] } @@ -117,7 +143,7 @@ func eightToFiveBits(_ input: [UInt8]) -> [UInt8] { } /// Decode Bech32 string -public func bech32_decode(_ str: String) throws -> (hrp: String, data: Data) { +public func bech32_decode(_ str: String) throws -> (hrp: String, data: Data)? { guard let strBytes = str.data(using: .utf8) else { throw Bech32Error.nonUTF8String } @@ -167,7 +193,11 @@ public func bech32_decode(_ str: String) throws -> (hrp: String, data: Data) { guard bech32_verify(hrp: hrp, checksum: values) else { throw Bech32Error.checksumMismatch } - return (hrp, Data(values[..<(vSize-6)])) + let out = Data(values[..<(vSize-6)]) + guard let converted = bech32_convert_bits(outbits: 8, input: out, inbits: 5, pad: 0) else { + return nil + } + return (hrp, converted) } public enum Bech32Error: LocalizedError {