mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd::b64: Add encoding diction parameter; remove converters; reorg interface.
This commit is contained in:
parent
486d9c1133
commit
44bd60ea08
5 changed files with 58 additions and 78 deletions
|
@ -13,29 +13,46 @@
|
|||
|
||||
namespace ircd::b64
|
||||
{
|
||||
[[gnu::aligned(64)]]
|
||||
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;
|
||||
static const auto
|
||||
&standard { dict_rfc1421 },
|
||||
&mailbox { dict_rfc3501 },
|
||||
&urlsafe { dict_rfc4648 };
|
||||
|
||||
// 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;
|
||||
constexpr size_t encode_size(const size_t &) noexcept;
|
||||
constexpr size_t encode_unpadded_size(const size_t &) noexcept;
|
||||
|
||||
size_t decode_size(const string_view &in) noexcept;
|
||||
size_t encode_size(const const_buffer &in) noexcept;
|
||||
size_t encode_unpadded_size(const const_buffer &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;
|
||||
template<const u8 (&dict)[64] = standard>
|
||||
string_view encode(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||
|
||||
template<const u8 (&dict)[64] = standard>
|
||||
string_view encode_unpadded(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::b64::encode_unpadded_size(const const_buffer &in)
|
||||
noexcept
|
||||
{
|
||||
return encode_unpadded_size(size(in));
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::b64::encode_size(const const_buffer &in)
|
||||
noexcept
|
||||
{
|
||||
return encode_size(size(in));
|
||||
}
|
||||
|
||||
inline size_t
|
||||
|
@ -45,20 +62,6 @@ 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
|
||||
|
@ -66,16 +69,16 @@ 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
|
||||
}
|
||||
|
||||
constexpr size_t
|
||||
ircd::b64::decode_size(const size_t &in)
|
||||
noexcept
|
||||
{
|
||||
return (in * 0.75) + 1; //XXX: constexpr ceil()
|
||||
}
|
||||
|
|
51
ircd/b64.cc
51
ircd/b64.cc
|
@ -24,6 +24,7 @@ namespace ircd::b64
|
|||
encode_permute_tab[64],
|
||||
encode_shift_ctrl[64];
|
||||
|
||||
template<const u8 (&dict)[64]>
|
||||
static u8x64 encode_block(const u8x64 in) noexcept;
|
||||
}
|
||||
#pragma GCC visibility pop
|
||||
|
@ -85,36 +86,9 @@ ircd::b64::encode_shift_ctrl
|
|||
(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.
|
||||
template<const ircd::u8 (&dict)[64]>
|
||||
ircd::string_view
|
||||
ircd::b64::encode(const mutable_buffer &out,
|
||||
const const_buffer &in)
|
||||
|
@ -127,7 +101,7 @@ noexcept
|
|||
|
||||
const auto encoded
|
||||
{
|
||||
encode_unpadded(out, in)
|
||||
encode_unpadded<dict>(out, in)
|
||||
};
|
||||
|
||||
assert(size(encoded) + pads <= size(out));
|
||||
|
@ -143,8 +117,11 @@ noexcept
|
|||
data(out), len
|
||||
};
|
||||
}
|
||||
template ircd::string_view ircd::b64::encode<ircd::b64::standard>(const mutable_buffer &, const const_buffer &) noexcept;
|
||||
template ircd::string_view ircd::b64::encode<ircd::b64::urlsafe>(const mutable_buffer &, const const_buffer &) noexcept;
|
||||
|
||||
/// Encoding in to base64 at out. Out must be 1.33+ larger than in.
|
||||
template<const ircd::u8 (&dict)[64]>
|
||||
ircd::string_view
|
||||
ircd::b64::encode_unpadded(const mutable_buffer &out,
|
||||
const const_buffer &in)
|
||||
|
@ -166,16 +143,16 @@ noexcept
|
|||
// Destination is indexed at 64 byte stride
|
||||
const auto di
|
||||
{
|
||||
reinterpret_cast<u512x1_u *>(data(out) + (i * 64))
|
||||
reinterpret_cast<u512x1_u *__restrict__>(data(out) + (i * 64))
|
||||
};
|
||||
|
||||
// Source is indexed at 48 byte stride
|
||||
const auto si
|
||||
{
|
||||
reinterpret_cast<const u512x1_u *>(data(in) + (i * 48))
|
||||
reinterpret_cast<const u512x1_u *__restrict__>(data(in) + (i * 48))
|
||||
};
|
||||
|
||||
*di = encode_block(*si);
|
||||
*di = encode_block<dict>(*si);
|
||||
}
|
||||
|
||||
for(; i * 48 < size(in); ++i)
|
||||
|
@ -184,7 +161,7 @@ noexcept
|
|||
for(j = 0; i * 48 + j < size(in); ++j)
|
||||
block[j] = in[i * 48 + j];
|
||||
|
||||
block = encode_block(block);
|
||||
block = encode_block<dict>(block);
|
||||
for(j = 0; i * 64 + j < out_len; ++j)
|
||||
out[i * 64 + j] = block[j];
|
||||
}
|
||||
|
@ -194,6 +171,8 @@ noexcept
|
|||
data(out), out_len
|
||||
};
|
||||
}
|
||||
template ircd::string_view ircd::b64::encode_unpadded<ircd::b64::standard>(const mutable_buffer &, const const_buffer &) noexcept;
|
||||
template ircd::string_view ircd::b64::encode_unpadded<ircd::b64::urlsafe>(const mutable_buffer &, const const_buffer &) noexcept;
|
||||
|
||||
/// Returns 64 base64-encoded characters from 48 input characters. For any
|
||||
/// inputs less than 48 characters trail with null characters; caller computes
|
||||
|
@ -206,15 +185,11 @@ noexcept
|
|||
/// 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.
|
||||
template<const ircd::u8 (&dict)[64]>
|
||||
ircd::u8x64
|
||||
ircd::b64::encode_block(const u8x64 in)
|
||||
noexcept
|
||||
{
|
||||
static const auto &dict
|
||||
{
|
||||
dict_rfc1421
|
||||
};
|
||||
|
||||
size_t i, j, k;
|
||||
|
||||
// vpermb
|
||||
|
|
|
@ -113,7 +113,7 @@ ircd::m::make_id(const event &event,
|
|||
{
|
||||
const id::event ret
|
||||
{
|
||||
buf, b64::tob64url(readable, b64::encode_unpadded(readable, hash)), at<"origin"_>(event)
|
||||
buf, b64::encode_unpadded<b64::urlsafe>(readable, hash), at<"origin"_>(event)
|
||||
};
|
||||
|
||||
buf.assigned(ret);
|
||||
|
@ -132,7 +132,7 @@ ircd::m::make_id(const event &event,
|
|||
|
||||
const id::event ret
|
||||
{
|
||||
buf, b64::tob64url(readable, b64::encode_unpadded(readable, hash)), string_view{}
|
||||
buf, b64::encode_unpadded<b64::urlsafe>(readable, hash), string_view{}
|
||||
};
|
||||
|
||||
buf.assigned(ret);
|
||||
|
|
|
@ -862,9 +862,11 @@ ircd::m::id::event::v4::v4(const mutable_buffer &out,
|
|||
};
|
||||
|
||||
out[0] = '$';
|
||||
string_view hashb64;
|
||||
hashb64 = b64::encode_unpadded(out + 1, hash);
|
||||
hashb64 = b64::tob64url(out + 1, hashb64);
|
||||
const string_view hashb64
|
||||
{
|
||||
b64::encode_unpadded<b64::urlsafe>(out + 1, hash)
|
||||
};
|
||||
|
||||
return string_view
|
||||
{
|
||||
ircd::data(out), 1 + ircd::size(hashb64)
|
||||
|
|
|
@ -33,7 +33,7 @@ ircd::m::user::filter::set(const mutable_buffer &idbuf,
|
|||
|
||||
const string_view filter_id
|
||||
{
|
||||
b64::tob64url(idbuf, b64::encode_unpadded(idbuf, hash))
|
||||
b64::encode_unpadded<b64::urlsafe>(idbuf, hash)
|
||||
};
|
||||
|
||||
//TODO: ABA
|
||||
|
|
Loading…
Reference in a new issue