mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd: Split base64 and base58 into separate namespaces.
This commit is contained in:
parent
1ab72aa258
commit
7ff89fbd17
21 changed files with 622 additions and 573 deletions
58
include/ircd/b58.h
Normal file
58
include/ircd/b58.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_B58_H
|
||||||
|
|
||||||
|
namespace ircd::b58
|
||||||
|
{
|
||||||
|
// Binary -> Base58 encode suite
|
||||||
|
constexpr size_t encode_size(const size_t &) noexcept;
|
||||||
|
size_t encode_size(const const_buffer &in) noexcept;
|
||||||
|
string_view encode(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||||
|
|
||||||
|
// Base58 -> Binary decode suite
|
||||||
|
constexpr size_t decode_size(const size_t &) noexcept;
|
||||||
|
size_t decode_size(const string_view &in) noexcept;
|
||||||
|
const_buffer decode(const mutable_buffer &out, const string_view &in);
|
||||||
|
|
||||||
|
// Convenience conversions
|
||||||
|
string_view tob64(const mutable_buffer &out, const string_view &in);
|
||||||
|
string_view tob64_unpadded(const mutable_buffer &out, const string_view &in);
|
||||||
|
string_view fromb64(const mutable_buffer &out, const string_view &in);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
ircd::b58::decode_size(const string_view &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return decode_size(size(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t
|
||||||
|
ircd::b58::decode_size(const size_t &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return in * 733UL / 1000UL + 1UL; // log(58) / log(256), rounded up
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
ircd::b58::encode_size(const const_buffer &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return encode_size(size(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t
|
||||||
|
ircd::b58::encode_size(const size_t &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return in * 138UL / 100UL + 1UL; // log(256) / log(58), rounded up
|
||||||
|
}
|
81
include/ircd/b64.h
Normal file
81
include/ircd/b64.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// Matrix Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_B64_H
|
||||||
|
|
||||||
|
namespace ircd::b64
|
||||||
|
{
|
||||||
|
extern const u8
|
||||||
|
dict_rfc1421[64], // [62] = '+', [63] = '/'
|
||||||
|
dict_rfc3501[64], // [62] = '+', [63] = ','
|
||||||
|
dict_rfc4648[64]; // [62] = '-', [63] = '_'
|
||||||
|
|
||||||
|
// Binary -> Base64 conversion suite
|
||||||
|
constexpr size_t encode_size(const size_t &) noexcept;
|
||||||
|
size_t encode_size(const const_buffer &in) noexcept;
|
||||||
|
string_view encode(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||||
|
|
||||||
|
// Binary -> Base64 conversion without padding
|
||||||
|
constexpr size_t encode_unpadded_size(const size_t &) noexcept;
|
||||||
|
size_t encode_unpadded_size(const const_buffer &in) noexcept;
|
||||||
|
string_view encode_unpadded(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||||
|
|
||||||
|
// Base64 -> Binary conversion (padded or unpadded)
|
||||||
|
constexpr size_t decode_size(const size_t &) noexcept;
|
||||||
|
size_t decode_size(const string_view &in) noexcept;
|
||||||
|
const_buffer decode(const mutable_buffer &out, const string_view &in);
|
||||||
|
|
||||||
|
// Base64 convenience conversions
|
||||||
|
string_view tob64url(const mutable_buffer &out, const string_view &in) noexcept;
|
||||||
|
string_view urltob64(const mutable_buffer &out, const string_view &in) noexcept;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
ircd::b64::decode_size(const string_view &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return decode_size(size(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t
|
||||||
|
ircd::b64::decode_size(const size_t &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return (in * 0.75) + 1; //XXX: constexpr ceil()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
ircd::b64::encode_unpadded_size(const const_buffer &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return encode_unpadded_size(size(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t
|
||||||
|
ircd::b64::encode_unpadded_size(const size_t &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return (in * (4.0 / 3.0)) + 1; //XXX: constexpr ceil()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
ircd::b64::encode_size(const const_buffer &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return encode_size(size(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t
|
||||||
|
ircd::b64::encode_size(const size_t &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return ((in * (4.0 / 3.0)) + 1) + (3 - in % 3) % 3; //XXX: constexpr ceil
|
||||||
|
}
|
|
@ -1,107 +0,0 @@
|
||||||
// Matrix Construct
|
|
||||||
//
|
|
||||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
||||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice is present in all copies. The
|
|
||||||
// full license for this software is available in the LICENSE file.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#define HAVE_IRCD_BASE_H
|
|
||||||
|
|
||||||
namespace ircd
|
|
||||||
{
|
|
||||||
// Binary -> Base58 encode suite
|
|
||||||
constexpr size_t b58encode_size(const size_t &);
|
|
||||||
size_t b58encode_size(const const_buffer &in);
|
|
||||||
string_view b58encode(const mutable_buffer &out, const const_buffer &in) noexcept;
|
|
||||||
|
|
||||||
// Base58 -> Binary decode suite
|
|
||||||
constexpr size_t b58decode_size(const size_t &);
|
|
||||||
size_t b58decode_size(const string_view &in);
|
|
||||||
const_buffer b58decode(const mutable_buffer &out, const string_view &in);
|
|
||||||
|
|
||||||
// Binary -> Base64 conversion suite
|
|
||||||
constexpr size_t b64encode_size(const size_t &);
|
|
||||||
size_t b64encode_size(const const_buffer &in);
|
|
||||||
string_view b64encode(const mutable_buffer &out, const const_buffer &in) noexcept;
|
|
||||||
|
|
||||||
// Binary -> Base64 conversion without padding
|
|
||||||
constexpr size_t b64encode_unpadded_size(const size_t &);
|
|
||||||
size_t b64encode_unpadded_size(const const_buffer &in);
|
|
||||||
string_view b64encode_unpadded(const mutable_buffer &out, const const_buffer &in) noexcept;
|
|
||||||
|
|
||||||
// Base64 -> Binary conversion (padded or unpadded)
|
|
||||||
constexpr size_t b64decode_size(const size_t &);
|
|
||||||
size_t b64decode_size(const string_view &in);
|
|
||||||
const_buffer b64decode(const mutable_buffer &out, const string_view &in);
|
|
||||||
|
|
||||||
// Base64 convenience conversions
|
|
||||||
string_view b64tob58(const mutable_buffer &out, const string_view &in);
|
|
||||||
string_view b58tob64(const mutable_buffer &out, const string_view &in);
|
|
||||||
string_view b58tob64_unpadded(const mutable_buffer &out, const string_view &in);
|
|
||||||
string_view b64tob64url(const mutable_buffer &out, const string_view &in) noexcept;
|
|
||||||
string_view b64urltob64(const mutable_buffer &out, const string_view &in) noexcept;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
|
||||||
ircd::b64decode_size(const string_view &in)
|
|
||||||
{
|
|
||||||
return b64decode_size(size(in));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t
|
|
||||||
ircd::b64decode_size(const size_t &in)
|
|
||||||
{
|
|
||||||
return (in * 0.75) + 1; //XXX: constexpr ceil()
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
|
||||||
ircd::b64encode_unpadded_size(const const_buffer &in)
|
|
||||||
{
|
|
||||||
return b64encode_unpadded_size(size(in));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t
|
|
||||||
ircd::b64encode_unpadded_size(const size_t &in)
|
|
||||||
{
|
|
||||||
return (in * (4.0 / 3.0)) + 1; //XXX: constexpr ceil()
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
|
||||||
ircd::b64encode_size(const const_buffer &in)
|
|
||||||
{
|
|
||||||
return b64encode_size(size(in));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t
|
|
||||||
ircd::b64encode_size(const size_t &in)
|
|
||||||
{
|
|
||||||
return ((in * (4.0 / 3.0)) + 1) + (3 - in % 3) % 3; //XXX: constexpr ceil
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
|
||||||
ircd::b58decode_size(const string_view &in)
|
|
||||||
{
|
|
||||||
return b58decode_size(size(in));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t
|
|
||||||
ircd::b58decode_size(const size_t &in)
|
|
||||||
{
|
|
||||||
return in * 733UL / 1000UL + 1UL; // log(58) / log(256), rounded up
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
|
||||||
ircd::b58encode_size(const const_buffer &in)
|
|
||||||
{
|
|
||||||
return b58encode_size(size(in));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t
|
|
||||||
ircd::b58encode_size(const size_t &in)
|
|
||||||
{
|
|
||||||
return in * 138UL / 100UL + 1UL; // log(256) / log(58), rounded up
|
|
||||||
}
|
|
|
@ -63,7 +63,8 @@
|
||||||
#include "fpe.h"
|
#include "fpe.h"
|
||||||
#include "rand.h"
|
#include "rand.h"
|
||||||
#include "crh.h"
|
#include "crh.h"
|
||||||
#include "base.h"
|
#include "b64.h"
|
||||||
|
#include "b58.h"
|
||||||
#include "stringops.h"
|
#include "stringops.h"
|
||||||
#include "strl.h"
|
#include "strl.h"
|
||||||
#include "strn.h"
|
#include "strn.h"
|
||||||
|
|
|
@ -131,7 +131,8 @@ libircd_la_SOURCES += globular.cc
|
||||||
libircd_la_SOURCES += tokens.cc
|
libircd_la_SOURCES += tokens.cc
|
||||||
libircd_la_SOURCES += parse.cc
|
libircd_la_SOURCES += parse.cc
|
||||||
libircd_la_SOURCES += rand.cc
|
libircd_la_SOURCES += rand.cc
|
||||||
libircd_la_SOURCES += base.cc
|
libircd_la_SOURCES += b64.cc
|
||||||
|
libircd_la_SOURCES += b58.cc
|
||||||
libircd_la_SOURCES += crh.cc
|
libircd_la_SOURCES += crh.cc
|
||||||
libircd_la_SOURCES += fmt.cc
|
libircd_la_SOURCES += fmt.cc
|
||||||
libircd_la_SOURCES += json.cc
|
libircd_la_SOURCES += json.cc
|
||||||
|
@ -204,7 +205,7 @@ libircd_la_SOURCES += ircd.cc
|
||||||
# Specific unit configurations
|
# Specific unit configurations
|
||||||
#
|
#
|
||||||
|
|
||||||
base.lo: AM_CPPFLAGS := @BOOST_CPPFLAGS@ ${AM_CPPFLAGS}
|
b64.lo: AM_CPPFLAGS := @BOOST_CPPFLAGS@ ${AM_CPPFLAGS}
|
||||||
client.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
client.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
||||||
ctx_x86_64.lo: AM_CPPFLAGS := -I$(top_srcdir)/include
|
ctx_x86_64.lo: AM_CPPFLAGS := -I$(top_srcdir)/include
|
||||||
ctx.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
ctx.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
||||||
|
|
164
ircd/b58.cc
Normal file
164
ircd/b58.cc
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
namespace ircd::b58
|
||||||
|
{
|
||||||
|
[[gnu::visibility("internal")]]
|
||||||
|
extern const string_view dict;
|
||||||
|
|
||||||
|
[[gnu::visibility("internal")]]
|
||||||
|
thread_local char conv_tmp_buf[64_KiB];
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype(ircd::b58::dict)
|
||||||
|
ircd::b58::dict
|
||||||
|
{
|
||||||
|
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"_sv
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conversion convenience suite
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b58::fromb64(const mutable_buffer &out,
|
||||||
|
const string_view &in)
|
||||||
|
{
|
||||||
|
if(unlikely(b64::decode_size(in) > size(conv_tmp_buf)))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"String too large for conversion at this time."
|
||||||
|
};
|
||||||
|
|
||||||
|
return b58::encode(out, b64::decode(conv_tmp_buf, in));
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b58::tob64_unpadded(const mutable_buffer &out,
|
||||||
|
const string_view &in)
|
||||||
|
{
|
||||||
|
if(unlikely(b58::decode_size(in) > size(conv_tmp_buf)))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"String too large for conversion at this time."
|
||||||
|
};
|
||||||
|
|
||||||
|
return b64::encode_unpadded(out, b58::decode(conv_tmp_buf, in));
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b58::tob64(const mutable_buffer &out,
|
||||||
|
const string_view &in)
|
||||||
|
{
|
||||||
|
if(unlikely(b58::decode_size(in) > size(conv_tmp_buf)))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"String too large for conversion at this time."
|
||||||
|
};
|
||||||
|
|
||||||
|
return b64::encode(out, b58::decode(conv_tmp_buf, in));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base58 decode
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::const_buffer
|
||||||
|
ircd::b58::decode(const mutable_buffer &buf,
|
||||||
|
const string_view &in)
|
||||||
|
{
|
||||||
|
auto p(begin(in));
|
||||||
|
size_t zeroes(0);
|
||||||
|
for(; p != end(in) && *p == '1'; ++p)
|
||||||
|
++zeroes;
|
||||||
|
|
||||||
|
const mutable_buffer out
|
||||||
|
{
|
||||||
|
data(buf) + zeroes, std::min(b58::decode_size(in), size(buf) - zeroes)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(size(out) + zeroes <= size(buf));
|
||||||
|
memset(data(out), 0, size(out));
|
||||||
|
|
||||||
|
size_t length(0);
|
||||||
|
for(size_t i(0); p != end(in); ++p, length = i, i = 0)
|
||||||
|
{
|
||||||
|
auto carry(dict.find(*p));
|
||||||
|
if(unlikely(carry == std::string::npos))
|
||||||
|
throw std::out_of_range
|
||||||
|
{
|
||||||
|
"Invalid base58 character"
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto it(rbegin(out)); (carry || i < length) && it != rend(out); ++it, i++)
|
||||||
|
{
|
||||||
|
carry += 58 * (*it);
|
||||||
|
*it = carry % 256;
|
||||||
|
carry /= 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it(begin(buf));
|
||||||
|
assert(it + zeroes + length <= end(buf));
|
||||||
|
for(; it != end(buf) && zeroes; *it++ = 0, --zeroes);
|
||||||
|
memmove(it, data(out) + (size(out) - length), length);
|
||||||
|
return const_buffer
|
||||||
|
{
|
||||||
|
begin(buf), it + length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base58 encode
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b58::encode(const mutable_buffer &buf,
|
||||||
|
const const_buffer &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
auto p(begin(in));
|
||||||
|
size_t zeroes(0);
|
||||||
|
for(; p != end(in) && *p == 0; ++p)
|
||||||
|
++zeroes;
|
||||||
|
|
||||||
|
const mutable_buffer out
|
||||||
|
{
|
||||||
|
data(buf) + zeroes, std::min(b58::encode_size(in), size(buf) - zeroes)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(size(out) + zeroes <= size(buf));
|
||||||
|
memset(data(out), 0, size(out));
|
||||||
|
|
||||||
|
size_t length(0);
|
||||||
|
for(size_t i(0); p != end(in); ++p, length = i, i = 0)
|
||||||
|
{
|
||||||
|
size_t carry(*p);
|
||||||
|
for(auto it(rbegin(out)); (carry || i < length) && it != rend(out); ++it, i++)
|
||||||
|
{
|
||||||
|
carry += 256 * (*it);
|
||||||
|
*it = carry % 58;
|
||||||
|
carry /= 58;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it(begin(buf));
|
||||||
|
assert(it + zeroes + length <= end(buf));
|
||||||
|
for(; it != end(buf) && zeroes; *it++ = '1', --zeroes);
|
||||||
|
memmove(it, data(out) + (size(out) - length), length);
|
||||||
|
return string_view
|
||||||
|
{
|
||||||
|
begin(buf), std::transform(it, it + length, it, []
|
||||||
|
(const uint8_t &in)
|
||||||
|
{
|
||||||
|
return dict.at(in);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
278
ircd/b64.cc
Normal file
278
ircd/b64.cc
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||||
|
#include <boost/archive/iterators/transform_width.hpp>
|
||||||
|
|
||||||
|
#pragma GCC visibility push(internal)
|
||||||
|
namespace ircd::b64
|
||||||
|
{
|
||||||
|
constexpr char pad
|
||||||
|
{
|
||||||
|
'='
|
||||||
|
};
|
||||||
|
|
||||||
|
[[gnu::aligned(64)]]
|
||||||
|
extern const u8
|
||||||
|
encode_permute_tab[64],
|
||||||
|
encode_shift_ctrl[64];
|
||||||
|
|
||||||
|
static u8x64 encode_block(const u8x64 in) noexcept;
|
||||||
|
}
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
decltype(ircd::b64::dict_rfc1421)
|
||||||
|
ircd::b64::dict_rfc1421
|
||||||
|
{
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
||||||
|
};
|
||||||
|
|
||||||
|
decltype(ircd::b64::dict_rfc3501)
|
||||||
|
ircd::b64::dict_rfc3501
|
||||||
|
{
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', ',',
|
||||||
|
};
|
||||||
|
|
||||||
|
decltype(ircd::b64::dict_rfc4648)
|
||||||
|
ircd::b64::dict_rfc4648
|
||||||
|
{
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
|
||||||
|
};
|
||||||
|
|
||||||
|
/// For vpermb
|
||||||
|
/// From arXiv:1910.05109v1 [Mula, Lemire] 2 Oct 2019
|
||||||
|
decltype(ircd::b64::encode_permute_tab)
|
||||||
|
ircd::b64::encode_permute_tab
|
||||||
|
{
|
||||||
|
0 + 1, 0 + 0, 0 + 2, 0 + 1, 3 + 1, 3 + 0, 3 + 2, 3 + 1,
|
||||||
|
6 + 1, 6 + 0, 6 + 2, 6 + 1, 9 + 1, 9 + 0, 9 + 2, 9 + 1,
|
||||||
|
12 + 1, 12 + 0, 12 + 2, 12 + 1, 15 + 1, 15 + 0, 15 + 2, 15 + 1,
|
||||||
|
18 + 1, 18 + 0, 18 + 2, 18 + 1, 21 + 1, 21 + 0, 21 + 2, 21 + 1,
|
||||||
|
24 + 1, 24 + 0, 24 + 2, 24 + 1, 27 + 1, 27 + 0, 27 + 2, 27 + 1,
|
||||||
|
30 + 1, 30 + 0, 30 + 2, 30 + 1, 33 + 1, 33 + 0, 33 + 2, 33 + 1,
|
||||||
|
36 + 1, 36 + 0, 36 + 2, 36 + 1, 39 + 1, 39 + 0, 39 + 2, 39 + 1,
|
||||||
|
42 + 1, 42 + 0, 42 + 2, 42 + 1, 45 + 1, 45 + 0, 45 + 2, 45 + 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// For vpmultishiftqb
|
||||||
|
/// From arXiv:1910.05109v1 [Mula, Lemire] 2 Oct 2019
|
||||||
|
decltype(ircd::b64::encode_shift_ctrl)
|
||||||
|
ircd::b64::encode_shift_ctrl
|
||||||
|
{
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0), (10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conversion convenience suite
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b64::urltob64(const mutable_buffer &out,
|
||||||
|
const string_view &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
//TODO: optimize with single pass
|
||||||
|
string_view ret(in);
|
||||||
|
ret = replace(out, ret, '-', '+');
|
||||||
|
ret = replace(out, ret, '_', '/');
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b64::tob64url(const mutable_buffer &out,
|
||||||
|
const string_view &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
//TODO: optimize with single pass
|
||||||
|
string_view ret(in);
|
||||||
|
ret = replace(out, ret, '+', '-');
|
||||||
|
ret = replace(out, ret, '/', '_');
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encoding in to base64 at out. Out must be 1.33+ larger than in
|
||||||
|
/// padding is not present in the returned view.
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b64::encode(const mutable_buffer &out,
|
||||||
|
const const_buffer &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
const auto pads
|
||||||
|
{
|
||||||
|
(3 - size(in) % 3) % 3
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto encoded
|
||||||
|
{
|
||||||
|
encode_unpadded(out, in)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(size(encoded) + pads <= size(out));
|
||||||
|
memset(data(out) + size(encoded), b64::pad, pads);
|
||||||
|
|
||||||
|
const auto len
|
||||||
|
{
|
||||||
|
size(encoded) + pads
|
||||||
|
};
|
||||||
|
|
||||||
|
return string_view
|
||||||
|
{
|
||||||
|
data(out), len
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encoding in to base64 at out. Out must be 1.33+ larger than in.
|
||||||
|
ircd::string_view
|
||||||
|
ircd::b64::encode_unpadded(const mutable_buffer &out,
|
||||||
|
const const_buffer &in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
const size_t res_len
|
||||||
|
{
|
||||||
|
size_t(ceil(size(in) * (4.0 / 3.0)))
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t out_len
|
||||||
|
{
|
||||||
|
std::min(res_len, size(out))
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t i(0), j(0);
|
||||||
|
for(; i + 1 < (size(in) / 48) && i < (out_len / 64); ++i)
|
||||||
|
{
|
||||||
|
// Destination is indexed at 64 byte stride
|
||||||
|
const auto di
|
||||||
|
{
|
||||||
|
reinterpret_cast<u512x1_u *>(data(out) + (i * 64))
|
||||||
|
};
|
||||||
|
|
||||||
|
// Source is indexed at 48 byte stride
|
||||||
|
const auto si
|
||||||
|
{
|
||||||
|
reinterpret_cast<const u512x1_u *>(data(in) + (i * 48))
|
||||||
|
};
|
||||||
|
|
||||||
|
*di = encode_block(*si);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; i * 48 < size(in); ++i)
|
||||||
|
{
|
||||||
|
u8x64 block{0};
|
||||||
|
for(j = 0; i * 48 + j < size(in); ++j)
|
||||||
|
block[j] = in[i * 48 + j];
|
||||||
|
|
||||||
|
block = encode_block(block);
|
||||||
|
for(j = 0; i * 64 + j < out_len; ++j)
|
||||||
|
out[i * 64 + j] = block[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return string_view
|
||||||
|
{
|
||||||
|
data(out), out_len
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns 64 base64-encoded characters from 48 input characters. For any
|
||||||
|
/// inputs less than 48 characters trail with null characters; caller computes
|
||||||
|
/// result size. The following operations are performed on each triple of input
|
||||||
|
/// characters resulting in four output characters:
|
||||||
|
/// 0. in[0] / 4;
|
||||||
|
/// 1. (in[1] / 16) + ((in[0] * 16) % 64);
|
||||||
|
/// 2. ((in[1] * 4) % 64) + (in[2] / 64);
|
||||||
|
/// 3. in[2] % 64;
|
||||||
|
/// Based on https://arxiv.org/pdf/1910.05109 (and earlier work). No specific
|
||||||
|
/// intrinsics are used here; instead we recite a kotodama divination known
|
||||||
|
/// as "vector extensions" which by chance is visible to humans as C syntax.
|
||||||
|
ircd::u8x64
|
||||||
|
ircd::b64::encode_block(const u8x64 in)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
static const auto &dict
|
||||||
|
{
|
||||||
|
dict_rfc1421
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t i, j, k;
|
||||||
|
|
||||||
|
// vpermb
|
||||||
|
u8x64 _perm;
|
||||||
|
for(k = 0; k < 64; ++k)
|
||||||
|
_perm[k] = in[encode_permute_tab[k]];
|
||||||
|
|
||||||
|
// TODO: currently does not achieve vpmultshiftqb on avx512vbmi
|
||||||
|
u64x8 sh[8], perm(_perm);
|
||||||
|
for(i = 0; i < 8; ++i)
|
||||||
|
for(j = 0; j < 8; ++j)
|
||||||
|
sh[i][j] = perm[i] >> encode_shift_ctrl[i * 8 + j];
|
||||||
|
|
||||||
|
// TODO: not needed if vpmultishiftqb is emitted.
|
||||||
|
for(i = 0; i < 8; ++i)
|
||||||
|
for(j = 0; j < 8; ++j)
|
||||||
|
sh[i][j] &= 0x3f;
|
||||||
|
|
||||||
|
u8x64 ret;
|
||||||
|
for(i = 0, k = 0; i < 8; ++i)
|
||||||
|
for(j = 0; j < 8; ++j)
|
||||||
|
ret[k++] = dict[sh[i][j]];
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base64 decode
|
||||||
|
//
|
||||||
|
|
||||||
|
/// Decode base64 from in to the buffer at out; out can be 75% of the size
|
||||||
|
/// of in.
|
||||||
|
ircd::const_buffer
|
||||||
|
ircd::b64::decode(const mutable_buffer &out,
|
||||||
|
const string_view &in)
|
||||||
|
{
|
||||||
|
namespace iterators = boost::archive::iterators;
|
||||||
|
using b64bf = iterators::binary_from_base64<const char *>;
|
||||||
|
using transform = iterators::transform_width<b64bf, 8, 6>;
|
||||||
|
|
||||||
|
const auto pads
|
||||||
|
{
|
||||||
|
endswith_count(in, b64::pad)
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto e
|
||||||
|
{
|
||||||
|
std::copy(transform(begin(in)), transform(begin(in) + size(in) - pads), begin(out))
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto len
|
||||||
|
{
|
||||||
|
std::distance(begin(out), e)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(size_t(len) <= size(out));
|
||||||
|
return const_buffer
|
||||||
|
{
|
||||||
|
data(out), size_t(len)
|
||||||
|
};
|
||||||
|
}
|
427
ircd/base.cc
427
ircd/base.cc
|
@ -1,427 +0,0 @@
|
||||||
// Matrix Construct
|
|
||||||
//
|
|
||||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
||||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice is present in all copies. The
|
|
||||||
// full license for this software is available in the LICENSE file.
|
|
||||||
|
|
||||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
|
||||||
#include <boost/archive/iterators/transform_width.hpp>
|
|
||||||
|
|
||||||
namespace ircd::base
|
|
||||||
{
|
|
||||||
[[gnu::visibility("internal")]]
|
|
||||||
thread_local char conv_tmp_buf[64_KiB];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Conversion convenience suite
|
|
||||||
//
|
|
||||||
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b64urltob64(const mutable_buffer &out,
|
|
||||||
const string_view &in)
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
//TODO: optimize with single pass
|
|
||||||
string_view ret(in);
|
|
||||||
ret = replace(out, ret, '-', '+');
|
|
||||||
ret = replace(out, ret, '_', '/');
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b64tob64url(const mutable_buffer &out,
|
|
||||||
const string_view &in)
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
//TODO: optimize with single pass
|
|
||||||
string_view ret(in);
|
|
||||||
ret = replace(out, ret, '+', '-');
|
|
||||||
ret = replace(out, ret, '/', '_');
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b58tob64_unpadded(const mutable_buffer &out,
|
|
||||||
const string_view &in)
|
|
||||||
{
|
|
||||||
if(unlikely(b58decode_size(in) > size(base::conv_tmp_buf)))
|
|
||||||
throw error
|
|
||||||
{
|
|
||||||
"String too large for conversion at this time."
|
|
||||||
};
|
|
||||||
|
|
||||||
return b64encode_unpadded(out, b58decode(base::conv_tmp_buf, in));
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b58tob64(const mutable_buffer &out,
|
|
||||||
const string_view &in)
|
|
||||||
{
|
|
||||||
if(unlikely(b58decode_size(in) > size(base::conv_tmp_buf)))
|
|
||||||
throw error
|
|
||||||
{
|
|
||||||
"String too large for conversion at this time."
|
|
||||||
};
|
|
||||||
|
|
||||||
return b64encode(out, b58decode(base::conv_tmp_buf, in));
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b64tob58(const mutable_buffer &out,
|
|
||||||
const string_view &in)
|
|
||||||
{
|
|
||||||
if(unlikely(b64decode_size(in) > size(base::conv_tmp_buf)))
|
|
||||||
throw error
|
|
||||||
{
|
|
||||||
"String too large for conversion at this time."
|
|
||||||
};
|
|
||||||
|
|
||||||
return b58encode(out, b64decode(base::conv_tmp_buf, in));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Base64 encode
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace ircd::base
|
|
||||||
{
|
|
||||||
constexpr char _b64_pad_
|
|
||||||
{
|
|
||||||
'='
|
|
||||||
};
|
|
||||||
|
|
||||||
[[using gnu: visibility("internal"), aligned(64)]]
|
|
||||||
extern const u8
|
|
||||||
b64_encode_permute_tab[64],
|
|
||||||
b64_encode_shift_ctrl[64];
|
|
||||||
|
|
||||||
[[using gnu: visibility("internal"), aligned(64)]]
|
|
||||||
extern const i32
|
|
||||||
b64_encode_lut[64];
|
|
||||||
|
|
||||||
static u8x64 b64encode(const u8x64 in) noexcept;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [00] - [25] => A - Z
|
|
||||||
// [26] - [51] => a - z
|
|
||||||
// [52] - [61] => 0 - 9
|
|
||||||
// [62], [63] => +, /
|
|
||||||
decltype(ircd::base::b64_encode_lut)
|
|
||||||
ircd::base::b64_encode_lut
|
|
||||||
{
|
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
|
||||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
|
||||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
|
||||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
|
||||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
|
||||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
|
||||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
|
||||||
'4', '5', '6', '7', '8', '9', '+', '/',
|
|
||||||
};
|
|
||||||
|
|
||||||
/// For vpermb
|
|
||||||
/// From arXiv:1910.05109v1 [Mula, Lemire] 2 Oct 2019
|
|
||||||
decltype(ircd::base::b64_encode_permute_tab)
|
|
||||||
ircd::base::b64_encode_permute_tab
|
|
||||||
{
|
|
||||||
0 + 1, 0 + 0, 0 + 2, 0 + 1,
|
|
||||||
3 + 1, 3 + 0, 3 + 2, 3 + 1,
|
|
||||||
6 + 1, 6 + 0, 6 + 2, 6 + 1,
|
|
||||||
9 + 1, 9 + 0, 9 + 2, 9 + 1,
|
|
||||||
12 + 1, 12 + 0, 12 + 2, 12 + 1,
|
|
||||||
15 + 1, 15 + 0, 15 + 2, 15 + 1,
|
|
||||||
18 + 1, 18 + 0, 18 + 2, 18 + 1,
|
|
||||||
21 + 1, 21 + 0, 21 + 2, 21 + 1,
|
|
||||||
24 + 1, 24 + 0, 24 + 2, 24 + 1,
|
|
||||||
27 + 1, 27 + 0, 27 + 2, 27 + 1,
|
|
||||||
30 + 1, 30 + 0, 30 + 2, 30 + 1,
|
|
||||||
33 + 1, 33 + 0, 33 + 2, 33 + 1,
|
|
||||||
36 + 1, 36 + 0, 36 + 2, 36 + 1,
|
|
||||||
39 + 1, 39 + 0, 39 + 2, 39 + 1,
|
|
||||||
42 + 1, 42 + 0, 42 + 2, 42 + 1,
|
|
||||||
45 + 1, 45 + 0, 45 + 2, 45 + 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// For vpmultishiftqb
|
|
||||||
/// From arXiv:1910.05109v1 [Mula, Lemire] 2 Oct 2019
|
|
||||||
decltype(ircd::base::b64_encode_shift_ctrl)
|
|
||||||
ircd::base::b64_encode_shift_ctrl
|
|
||||||
{
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
(10 + 0), ( 4 + 0), (22 + 0), (16 + 0),
|
|
||||||
(10 + 32), ( 4 + 32), (22 + 32), (16 + 32),
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Encoding in to base64 at out. Out must be 1.33+ larger than in
|
|
||||||
/// padding is not present in the returned view.
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b64encode(const mutable_buffer &out,
|
|
||||||
const const_buffer &in)
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
const auto pads
|
|
||||||
{
|
|
||||||
(3 - size(in) % 3) % 3
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto encoded
|
|
||||||
{
|
|
||||||
b64encode_unpadded(out, in)
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(size(encoded) + pads <= size(out));
|
|
||||||
memset(data(out) + size(encoded), base::_b64_pad_, pads);
|
|
||||||
|
|
||||||
const auto len
|
|
||||||
{
|
|
||||||
size(encoded) + pads
|
|
||||||
};
|
|
||||||
|
|
||||||
return { data(out), len };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encoding in to base64 at out. Out must be 1.33+ larger than in.
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b64encode_unpadded(const mutable_buffer &out,
|
|
||||||
const const_buffer &in)
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
const size_t res_len
|
|
||||||
{
|
|
||||||
size_t(ceil(size(in) * (4.0 / 3.0)))
|
|
||||||
};
|
|
||||||
|
|
||||||
const size_t out_len
|
|
||||||
{
|
|
||||||
std::min(res_len, size(out))
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t i(0), j(0);
|
|
||||||
for(; i + 1 < (size(in) / 48) && i < (out_len / 64); ++i)
|
|
||||||
{
|
|
||||||
// Destination is indexed at 64 byte stride
|
|
||||||
const auto di
|
|
||||||
{
|
|
||||||
reinterpret_cast<u512x1_u *>(data(out) + (i * 64))
|
|
||||||
};
|
|
||||||
|
|
||||||
// Source is indexed at 48 byte stride
|
|
||||||
const auto si
|
|
||||||
{
|
|
||||||
reinterpret_cast<const u512x1_u *>(data(in) + (i * 48))
|
|
||||||
};
|
|
||||||
|
|
||||||
*di = base::b64encode(*si);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(; i * 48 < size(in); ++i)
|
|
||||||
{
|
|
||||||
u8x64 block{0};
|
|
||||||
for(j = 0; i * 48 + j < size(in); ++j)
|
|
||||||
block[j] = in[i * 48 + j];
|
|
||||||
|
|
||||||
block = base::b64encode(block);
|
|
||||||
for(j = 0; i * 64 + j < out_len; ++j)
|
|
||||||
out[i * 64 + j] = block[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_view
|
|
||||||
{
|
|
||||||
data(out), out_len
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns 64 base64-encoded characters from 48 input characters. For any
|
|
||||||
/// inputs less than 48 characters trail with null characters; caller computes
|
|
||||||
/// result size. The following operations are performed on each triple of input
|
|
||||||
/// characters resulting in four output characters:
|
|
||||||
/// 0. in[0] / 4;
|
|
||||||
/// 1. (in[1] / 16) + ((in[0] * 16) % 64);
|
|
||||||
/// 2. ((in[1] * 4) % 64) + (in[2] / 64);
|
|
||||||
/// 3. in[2] % 64;
|
|
||||||
/// Based on https://arxiv.org/pdf/1910.05109 (and earlier work). No specific
|
|
||||||
/// intrinsics are used here; instead we recite a kotodama divination known
|
|
||||||
/// as "vector extensions" which by chance is visible to humans as C syntax.
|
|
||||||
ircd::u8x64
|
|
||||||
ircd::base::b64encode(const u8x64 in)
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
size_t i, j, k;
|
|
||||||
|
|
||||||
// vpermb
|
|
||||||
u8x64 _perm;
|
|
||||||
for(k = 0; k < 64; ++k)
|
|
||||||
_perm[k] = in[b64_encode_permute_tab[k]];
|
|
||||||
|
|
||||||
// TODO: currently does not achieve vpmultshiftqb on avx512vbmi
|
|
||||||
u64x8 sh[8], perm(_perm);
|
|
||||||
for(i = 0; i < 8; ++i)
|
|
||||||
for(j = 0; j < 8; ++j)
|
|
||||||
sh[i][j] = perm[i] >> b64_encode_shift_ctrl[i * 8 + j];
|
|
||||||
|
|
||||||
// TODO: not needed if vpmultishiftqb is emitted.
|
|
||||||
for(i = 0; i < 8; ++i)
|
|
||||||
for(j = 0; j < 8; ++j)
|
|
||||||
sh[i][j] &= 0x3f;
|
|
||||||
|
|
||||||
u8x64 ret;
|
|
||||||
for(i = 0, k = 0; i < 8; ++i)
|
|
||||||
for(j = 0; j < 8; ++j)
|
|
||||||
ret[k++] = b64_encode_lut[sh[i][j]];
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Base64 decode
|
|
||||||
//
|
|
||||||
|
|
||||||
/// Decode base64 from in to the buffer at out; out can be 75% of the size
|
|
||||||
/// of in.
|
|
||||||
ircd::const_buffer
|
|
||||||
ircd::b64decode(const mutable_buffer &out,
|
|
||||||
const string_view &in)
|
|
||||||
{
|
|
||||||
namespace iterators = boost::archive::iterators;
|
|
||||||
using b64bf = iterators::binary_from_base64<const char *>;
|
|
||||||
using transform = iterators::transform_width<b64bf, 8, 6>;
|
|
||||||
|
|
||||||
const auto pads
|
|
||||||
{
|
|
||||||
endswith_count(in, base::_b64_pad_)
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto e
|
|
||||||
{
|
|
||||||
std::copy(transform(begin(in)), transform(begin(in) + size(in) - pads), begin(out))
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto len
|
|
||||||
{
|
|
||||||
std::distance(begin(out), e)
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(size_t(len) <= size(out));
|
|
||||||
return { data(out), size_t(len) };
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Base58
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace ircd::base
|
|
||||||
{
|
|
||||||
static const auto &b58
|
|
||||||
{
|
|
||||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"s
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Base58 decode
|
|
||||||
//
|
|
||||||
|
|
||||||
ircd::const_buffer
|
|
||||||
ircd::b58decode(const mutable_buffer &buf,
|
|
||||||
const string_view &in)
|
|
||||||
{
|
|
||||||
auto p(begin(in));
|
|
||||||
size_t zeroes(0);
|
|
||||||
for(; p != end(in) && *p == '1'; ++p)
|
|
||||||
++zeroes;
|
|
||||||
|
|
||||||
const mutable_buffer out
|
|
||||||
{
|
|
||||||
data(buf) + zeroes, std::min(b58decode_size(in), size(buf) - zeroes)
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(size(out) + zeroes <= size(buf));
|
|
||||||
memset(data(out), 0, size(out));
|
|
||||||
|
|
||||||
size_t length(0);
|
|
||||||
for(size_t i(0); p != end(in); ++p, length = i, i = 0)
|
|
||||||
{
|
|
||||||
auto carry(base::b58.find(*p));
|
|
||||||
if(carry == std::string::npos)
|
|
||||||
throw std::out_of_range("Invalid base58 character");
|
|
||||||
|
|
||||||
for(auto it(rbegin(out)); (carry || i < length) && it != rend(out); ++it, i++)
|
|
||||||
{
|
|
||||||
carry += 58 * (*it);
|
|
||||||
*it = carry % 256;
|
|
||||||
carry /= 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it(begin(buf));
|
|
||||||
assert(it + zeroes + length <= end(buf));
|
|
||||||
for(; it != end(buf) && zeroes; *it++ = 0, --zeroes);
|
|
||||||
memmove(it, data(out) + (size(out) - length), length);
|
|
||||||
return { begin(buf), it + length };
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Base58 encode
|
|
||||||
//
|
|
||||||
|
|
||||||
ircd::string_view
|
|
||||||
ircd::b58encode(const mutable_buffer &buf,
|
|
||||||
const const_buffer &in)
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
auto p(begin(in));
|
|
||||||
size_t zeroes(0);
|
|
||||||
for(; p != end(in) && *p == 0; ++p)
|
|
||||||
++zeroes;
|
|
||||||
|
|
||||||
const mutable_buffer out
|
|
||||||
{
|
|
||||||
data(buf) + zeroes, std::min(b58encode_size(in), size(buf) - zeroes)
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(size(out) + zeroes <= size(buf));
|
|
||||||
memset(data(out), 0, size(out));
|
|
||||||
|
|
||||||
size_t length(0);
|
|
||||||
for(size_t i(0); p != end(in); ++p, length = i, i = 0)
|
|
||||||
{
|
|
||||||
size_t carry(*p);
|
|
||||||
for(auto it(rbegin(out)); (carry || i < length) && it != rend(out); ++it, i++)
|
|
||||||
{
|
|
||||||
carry += 256 * (*it);
|
|
||||||
*it = carry % 58;
|
|
||||||
carry /= 58;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it(begin(buf));
|
|
||||||
assert(it + zeroes + length <= end(buf));
|
|
||||||
for(; it != end(buf) && zeroes; *it++ = '1', --zeroes);
|
|
||||||
memmove(it, data(out) + (size(out) - length), length);
|
|
||||||
return
|
|
||||||
{
|
|
||||||
begin(buf), std::transform(it, it + length, it, []
|
|
||||||
(const uint8_t &in)
|
|
||||||
{
|
|
||||||
return base::b58.at(in);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -123,7 +123,7 @@ ircd::net::peer_cert_der_sha256_b64(const mutable_buffer &buf,
|
||||||
peer_cert_der_sha256(shabuf, socket)
|
peer_cert_der_sha256(shabuf, socket)
|
||||||
};
|
};
|
||||||
|
|
||||||
return b64encode_unpadded(buf, hash);
|
return b64::encode_unpadded(buf, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::const_buffer
|
ircd::const_buffer
|
||||||
|
|
|
@ -107,13 +107,13 @@ ircd::m::make_id(const event &event,
|
||||||
id::event::buf &buf,
|
id::event::buf &buf,
|
||||||
const const_buffer &hash)
|
const const_buffer &hash)
|
||||||
{
|
{
|
||||||
char readable[b64encode_size(sha256::digest_size)];
|
char readable[b64::encode_size(sha256::digest_size)];
|
||||||
|
|
||||||
if(version == "1" || version == "2")
|
if(version == "1" || version == "2")
|
||||||
{
|
{
|
||||||
const id::event ret
|
const id::event ret
|
||||||
{
|
{
|
||||||
buf, b64tob64url(readable, b64encode_unpadded(readable, hash)), at<"origin"_>(event)
|
buf, b64::tob64url(readable, b64::encode_unpadded(readable, hash)), at<"origin"_>(event)
|
||||||
};
|
};
|
||||||
|
|
||||||
buf.assigned(ret);
|
buf.assigned(ret);
|
||||||
|
@ -123,7 +123,7 @@ ircd::m::make_id(const event &event,
|
||||||
{
|
{
|
||||||
const id::event ret
|
const id::event ret
|
||||||
{
|
{
|
||||||
buf, b64encode_unpadded(readable, hash), string_view{}
|
buf, b64::encode_unpadded(readable, hash), string_view{}
|
||||||
};
|
};
|
||||||
|
|
||||||
buf.assigned(ret);
|
buf.assigned(ret);
|
||||||
|
@ -132,7 +132,7 @@ ircd::m::make_id(const event &event,
|
||||||
|
|
||||||
const id::event ret
|
const id::event ret
|
||||||
{
|
{
|
||||||
buf, b64tob64url(readable, b64encode_unpadded(readable, hash)), string_view{}
|
buf, b64::tob64url(readable, b64::encode_unpadded(readable, hash)), string_view{}
|
||||||
};
|
};
|
||||||
|
|
||||||
buf.assigned(ret);
|
buf.assigned(ret);
|
||||||
|
@ -168,11 +168,11 @@ ircd::json::object
|
||||||
ircd::m::make_hashes(const mutable_buffer &out,
|
ircd::m::make_hashes(const mutable_buffer &out,
|
||||||
const sha256::buf &hash)
|
const sha256::buf &hash)
|
||||||
{
|
{
|
||||||
static const auto b64bufsz(b64encode_size(sizeof(hash)));
|
static const auto b64bufsz(b64::encode_size(sizeof(hash)));
|
||||||
thread_local char hashb64buf[b64bufsz];
|
thread_local char hashb64buf[b64bufsz];
|
||||||
const json::members hashes
|
const json::members hashes
|
||||||
{
|
{
|
||||||
{ "sha256", b64encode_unpadded(hashb64buf, hash) }
|
{ "sha256", b64::encode_unpadded(hashb64buf, hash) }
|
||||||
};
|
};
|
||||||
|
|
||||||
return json::stringify(mutable_buffer{out}, hashes);
|
return json::stringify(mutable_buffer{out}, hashes);
|
||||||
|
@ -245,7 +245,7 @@ ircd::m::verify_hash(const event &event,
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local char b64buf[hashb64sz];
|
thread_local char b64buf[hashb64sz];
|
||||||
return verify_sha256b64(event, b64encode_unpadded(b64buf, hash));
|
return verify_sha256b64(event, b64::encode_unpadded(b64buf, hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -290,10 +290,10 @@ ircd::m::event::signatures(const mutable_buffer &out,
|
||||||
m::public_key_id(m::my(origin))
|
m::public_key_id(m::my(origin))
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local char sigb64buf[b64encode_size(sizeof(sig))];
|
thread_local char sigb64buf[b64::encode_size(sizeof(sig))];
|
||||||
const json::members sigb64
|
const json::members sigb64
|
||||||
{
|
{
|
||||||
{ public_key_id, b64encode_unpadded(sigb64buf, sig) }
|
{ public_key_id, b64::encode_unpadded(sigb64buf, sig) }
|
||||||
};
|
};
|
||||||
|
|
||||||
const json::members sigs
|
const json::members sigs
|
||||||
|
@ -350,7 +350,7 @@ ircd::m::signatures(const mutable_buffer &out_,
|
||||||
|
|
||||||
static const auto sigb64bufsz
|
static const auto sigb64bufsz
|
||||||
{
|
{
|
||||||
b64encode_size(sizeof(my_sig))
|
b64::encode_size(sizeof(my_sig))
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local char sigb64buf[sigb64bufsz];
|
thread_local char sigb64buf[sigb64bufsz];
|
||||||
|
@ -358,7 +358,7 @@ ircd::m::signatures(const mutable_buffer &out_,
|
||||||
{
|
{
|
||||||
origin, json::members
|
origin, json::members
|
||||||
{
|
{
|
||||||
{ public_key_id, b64encode_unpadded(sigb64buf, my_sig) }
|
{ public_key_id, b64::encode_unpadded(sigb64buf, my_sig) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -600,7 +600,7 @@ ircd::m::verify(const event &event,
|
||||||
{
|
{
|
||||||
[&origin_sigs, &keyid](auto &buf)
|
[&origin_sigs, &keyid](auto &buf)
|
||||||
{
|
{
|
||||||
b64decode(buf, json::string(origin_sigs.at(keyid)));
|
b64::decode(buf, json::string(origin_sigs.at(keyid)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -384,7 +384,7 @@ ircd::m::homeserver::key::key(const struct opts &opts)
|
||||||
{
|
{
|
||||||
ircd::string(96, [this](const mutable_buffer &buf)
|
ircd::string(96, [this](const mutable_buffer &buf)
|
||||||
{
|
{
|
||||||
return b64encode_unpadded(buf, public_key);
|
return b64::encode_unpadded(buf, public_key);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
,public_key_id
|
,public_key_id
|
||||||
|
@ -433,7 +433,7 @@ ircd::m::homeserver::key::key(const struct opts &opts)
|
||||||
{
|
{
|
||||||
{ opts.origin, json::member
|
{ opts.origin, json::member
|
||||||
{
|
{
|
||||||
public_key_id, b64encode_unpadded(buf[1], sig)
|
public_key_id, b64::encode_unpadded(buf[1], sig)
|
||||||
}}
|
}}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
@ -793,7 +793,7 @@ ircd::m::id::event::v3::v3(const mutable_buffer &out,
|
||||||
out[0] = '$';
|
out[0] = '$';
|
||||||
const string_view hashb64
|
const string_view hashb64
|
||||||
{
|
{
|
||||||
b64encode_unpadded(out + 1, hash)
|
b64::encode_unpadded(out + 1, hash)
|
||||||
};
|
};
|
||||||
|
|
||||||
return string_view
|
return string_view
|
||||||
|
@ -863,8 +863,8 @@ ircd::m::id::event::v4::v4(const mutable_buffer &out,
|
||||||
|
|
||||||
out[0] = '$';
|
out[0] = '$';
|
||||||
string_view hashb64;
|
string_view hashb64;
|
||||||
hashb64 = b64encode_unpadded(out + 1, hash);
|
hashb64 = b64::encode_unpadded(out + 1, hash);
|
||||||
hashb64 = b64tob64url(out + 1, hashb64);
|
hashb64 = b64::tob64url(out + 1, hashb64);
|
||||||
return string_view
|
return string_view
|
||||||
{
|
{
|
||||||
ircd::data(out), 1 + ircd::size(hashb64)
|
ircd::data(out), 1 + ircd::size(hashb64)
|
||||||
|
|
|
@ -123,7 +123,7 @@ ircd::m::verify(const m::keys &keys)
|
||||||
{
|
{
|
||||||
[&key](auto &pk)
|
[&key](auto &pk)
|
||||||
{
|
{
|
||||||
b64decode(pk, unquote(key.at("key")));
|
b64::decode(pk, unquote(key.at("key")));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ ircd::m::verify(const m::keys &keys)
|
||||||
{
|
{
|
||||||
[&server_signatures, &key_id](auto &sig)
|
[&server_signatures, &key_id](auto &sig)
|
||||||
{
|
{
|
||||||
b64decode(sig, unquote(server_signatures.at(key_id)));
|
b64::decode(sig, unquote(server_signatures.at(key_id)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -639,7 +639,7 @@ noexcept try
|
||||||
char seed_buf[ed25519::SEED_SZ + 10];
|
char seed_buf[ed25519::SEED_SZ + 10];
|
||||||
const auto seed
|
const auto seed
|
||||||
{
|
{
|
||||||
b64decode(seed_buf, "YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA1")
|
b64::decode(seed_buf, "YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA1")
|
||||||
};
|
};
|
||||||
|
|
||||||
ed25519::pk pk;
|
ed25519::pk pk;
|
||||||
|
@ -659,12 +659,12 @@ noexcept try
|
||||||
char sigb64_buf[128];
|
char sigb64_buf[128];
|
||||||
const auto sigb64
|
const auto sigb64
|
||||||
{
|
{
|
||||||
b64encode_unpadded(sigb64_buf, sig)
|
b64::encode_unpadded(sigb64_buf, sig)
|
||||||
};
|
};
|
||||||
|
|
||||||
ed25519::sig unsig; const auto unsigb64
|
ed25519::sig unsig; const auto unsigb64
|
||||||
{
|
{
|
||||||
b64decode(unsig, sigb64)
|
b64::decode(unsig, sigb64)
|
||||||
};
|
};
|
||||||
|
|
||||||
return pk.verify(const_buffer{object}, unsig);
|
return pk.verify(const_buffer{object}, unsig);
|
||||||
|
|
|
@ -77,7 +77,7 @@ ircd::m::node::room::room(const m::node &node)
|
||||||
|
|
||||||
const string_view b58
|
const string_view b58
|
||||||
{
|
{
|
||||||
b58encode(buf, hash)
|
b58::encode(buf, hash)
|
||||||
};
|
};
|
||||||
|
|
||||||
return id::room::buf
|
return id::room::buf
|
||||||
|
@ -105,7 +105,7 @@ const
|
||||||
{
|
{
|
||||||
[&keyb64](auto &buf)
|
[&keyb64](auto &buf)
|
||||||
{
|
{
|
||||||
b64decode(buf, keyb64);
|
b64::decode(buf, keyb64);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ ircd::m::pretty_detailed(std::ostream &out,
|
||||||
char buf[512];
|
char buf[512];
|
||||||
out
|
out
|
||||||
<< std::setw(9) << std::left << "!!! ERROR" << " "
|
<< std::setw(9) << std::left << "!!! ERROR" << " "
|
||||||
<< "HASH MISMATCH :" << b64encode_unpadded(buf, hash(event))
|
<< "HASH MISMATCH :" << b64::encode_unpadded(buf, hash(event))
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ const
|
||||||
out, "X-Matrix origin=%s,key=\"%s\",sig=\"%s\"",
|
out, "X-Matrix origin=%s,key=\"%s\",sig=\"%s\"",
|
||||||
origin,
|
origin,
|
||||||
pkid,
|
pkid,
|
||||||
b64encode_unpadded(sigb64, sig)
|
b64::encode_unpadded(sigb64, sig)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ const
|
||||||
{
|
{
|
||||||
[&sig_](auto &buf)
|
[&sig_](auto &buf)
|
||||||
{
|
{
|
||||||
b64decode(buf, sig_);
|
b64::decode(buf, sig_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ ircd::m::txn::create_id(const mutable_buffer &out,
|
||||||
|
|
||||||
const string_view txnid
|
const string_view txnid
|
||||||
{
|
{
|
||||||
b58encode(out, hash)
|
b58::encode(out, hash)
|
||||||
};
|
};
|
||||||
|
|
||||||
return txnid;
|
return txnid;
|
||||||
|
|
|
@ -145,7 +145,7 @@ const
|
||||||
char b58[size(hash) * 2];
|
char b58[size(hash) * 2];
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
buf, b58encode(b58, hash), origin(my())
|
buf, b58::encode(b58, hash), origin(my())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ ircd::m::gen_password_hash(const mutable_buffer &out,
|
||||||
sha256{supplied_password}
|
sha256{supplied_password}
|
||||||
};
|
};
|
||||||
|
|
||||||
return b64encode_unpadded(out, hash);
|
return b64::encode_unpadded(out, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -33,7 +33,7 @@ ircd::m::user::filter::set(const mutable_buffer &idbuf,
|
||||||
|
|
||||||
const string_view filter_id
|
const string_view filter_id
|
||||||
{
|
{
|
||||||
b64tob64url(idbuf, b64encode_unpadded(idbuf, hash))
|
b64::tob64url(idbuf, b64::encode_unpadded(idbuf, hash))
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: ABA
|
//TODO: ABA
|
||||||
|
|
|
@ -6895,7 +6895,7 @@ console_cmd__stage(opt &out, const string_view &line)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
if(!verify_hash(event))
|
if(!verify_hash(event))
|
||||||
out << "- HASH MISMATCH: " << b64encode_unpadded(buf, hash(event)) << std::endl;
|
out << "- HASH MISMATCH: " << b64::encode_unpadded(buf, hash(event)) << std::endl;
|
||||||
}
|
}
|
||||||
catch(const std::exception &e)
|
catch(const std::exception &e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -615,7 +615,7 @@ ircd::m::media::file::room_id(room::id::buf &out,
|
||||||
|
|
||||||
out =
|
out =
|
||||||
{
|
{
|
||||||
b58encode(buf, hash), my_host()
|
b58::encode(buf, hash), my_host()
|
||||||
};
|
};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -633,7 +633,7 @@ ircd::m::media::block::set(const m::room &room,
|
||||||
{
|
{
|
||||||
static constexpr const auto bufsz
|
static constexpr const auto bufsz
|
||||||
{
|
{
|
||||||
b58encode_size(sha256::digest_size)
|
b58::encode_size(sha256::digest_size)
|
||||||
};
|
};
|
||||||
|
|
||||||
char b58buf[bufsz];
|
char b58buf[bufsz];
|
||||||
|
@ -661,7 +661,7 @@ ircd::m::media::block::set(const mutable_buffer &b58buf,
|
||||||
|
|
||||||
const string_view b58hash
|
const string_view b58hash
|
||||||
{
|
{
|
||||||
b58encode(b58buf, hash)
|
b58::encode(b58buf, hash)
|
||||||
};
|
};
|
||||||
|
|
||||||
set(b58hash, block);
|
set(b58hash, block);
|
||||||
|
|
Loading…
Reference in a new issue