I’m trying to figure out how to verify a signature that’s generated using a Tezos crypto wallet on the client-side. From the wallet, I get the signed message and the wallet’s public key, and the message is known to me because it’s generated on the server before signing.
Don’t know what all you need, but if it’s just converting Bytes to String and vice versa, this should probably do it:
require "big"
T= "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def encode (bytes : Bytes) : String
r= Array(Char).new
big= bytes.reduce(BigInt.new){|b, c| b*256+c}
while big > 0
r << T[(big%58).to_i32]
big//= 58
end
r.reverse.join
end
def decode (string : String) : Bytes
r= IO::Memory.new
big= string.chars.reduce(BigInt.new){|b, c| b*58+(T.index(c)||(raise "nope!"))}
while big > 0
r.write_byte (big%256).to_u8
big//= 256
end
r.to_slice.reverse!
end
If this seems to fit your needs, make sure before you use it for anything serious, that it works really always as you expect it, because I didn’t do so.
Also, depending on how often you have to use it, this likely won’t be the most performant option (BigInt does the job, but in this particular case it probably shouldn’t be your first choice should performance matter).
That lib made me realise I was using the wrong alphabet. GitHub - russ/base58: base58 for Crystal references the one used by Flickr, while I needed the one for Bitcoin.
I decided to port it to Crystal:
Your solutions look more elegant, so if that’s ok with you, I’m going to rework the shard a bit starting off the examples above. Maybe rename it base_x so it isn’t restricted to base58.