16 changes: 8 additions & 8 deletions src/lib/block/des/des_tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Botan {

const uint32_t DES_SPBOX1[256] = {
alignas(64) const uint32_t DES_SPBOX1[256] = {
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
Expand Down Expand Up @@ -54,7 +54,7 @@ const uint32_t DES_SPBOX1[256] = {
0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004 };

const uint32_t DES_SPBOX2[256] = {
alignas(64) const uint32_t DES_SPBOX2[256] = {
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
Expand Down Expand Up @@ -99,7 +99,7 @@ const uint32_t DES_SPBOX2[256] = {
0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000 };

const uint32_t DES_SPBOX3[256] = {
alignas(64) const uint32_t DES_SPBOX3[256] = {
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
Expand Down Expand Up @@ -144,7 +144,7 @@ const uint32_t DES_SPBOX3[256] = {
0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200 };

const uint32_t DES_SPBOX4[256] = {
alignas(64) const uint32_t DES_SPBOX4[256] = {
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
Expand Down Expand Up @@ -189,7 +189,7 @@ const uint32_t DES_SPBOX4[256] = {
0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080 };

const uint32_t DES_SPBOX5[256] = {
alignas(64) const uint32_t DES_SPBOX5[256] = {
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
Expand Down Expand Up @@ -234,7 +234,7 @@ const uint32_t DES_SPBOX5[256] = {
0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100 };

const uint32_t DES_SPBOX6[256] = {
alignas(64) const uint32_t DES_SPBOX6[256] = {
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
Expand Down Expand Up @@ -279,7 +279,7 @@ const uint32_t DES_SPBOX6[256] = {
0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010 };

const uint32_t DES_SPBOX7[256] = {
alignas(64) const uint32_t DES_SPBOX7[256] = {
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
Expand Down Expand Up @@ -324,7 +324,7 @@ const uint32_t DES_SPBOX7[256] = {
0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002 };

const uint32_t DES_SPBOX8[256] = {
alignas(64) const uint32_t DES_SPBOX8[256] = {
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/block/kasumi/kasumi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace {
/*
* KASUMI S-Boxes
*/
const uint8_t KASUMI_SBOX_S7[128] = {
alignas(64) const uint8_t KASUMI_SBOX_S7[128] = {
0x36, 0x32, 0x3E, 0x38, 0x16, 0x22, 0x5E, 0x60, 0x26, 0x06, 0x3F, 0x5D,
0x02, 0x12, 0x7B, 0x21, 0x37, 0x71, 0x27, 0x72, 0x15, 0x43, 0x41, 0x0C,
0x2F, 0x49, 0x2E, 0x1B, 0x19, 0x6F, 0x7C, 0x51, 0x35, 0x09, 0x79, 0x4F,
Expand All @@ -29,7 +29,7 @@ const uint8_t KASUMI_SBOX_S7[128] = {
0x44, 0x1D, 0x73, 0x2C, 0x40, 0x6B, 0x6C, 0x18, 0x6E, 0x53, 0x24, 0x4E,
0x2A, 0x13, 0x0F, 0x29, 0x58, 0x77, 0x3B, 0x03 };

const uint16_t KASUMI_SBOX_S9[512] = {
alignas(64) const uint16_t KASUMI_SBOX_S9[512] = {
0x00A7, 0x00EF, 0x00A1, 0x017B, 0x0187, 0x014E, 0x0009, 0x0152, 0x0026,
0x00E2, 0x0030, 0x0166, 0x01C4, 0x0181, 0x005A, 0x018D, 0x00B7, 0x00FD,
0x0093, 0x014B, 0x019F, 0x0154, 0x0033, 0x016A, 0x0132, 0x01F4, 0x0106,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/block/misty1/misty1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Botan {

namespace {

static const uint8_t MISTY1_SBOX_S7[128] = {
alignas(64) static const uint8_t MISTY1_SBOX_S7[128] = {
0x1B, 0x32, 0x33, 0x5A, 0x3B, 0x10, 0x17, 0x54, 0x5B, 0x1A, 0x72, 0x73,
0x6B, 0x2C, 0x66, 0x49, 0x1F, 0x24, 0x13, 0x6C, 0x37, 0x2E, 0x3F, 0x4A,
0x5D, 0x0F, 0x40, 0x56, 0x25, 0x51, 0x1C, 0x04, 0x0B, 0x46, 0x20, 0x0D,
Expand All @@ -25,7 +25,7 @@ static const uint8_t MISTY1_SBOX_S7[128] = {
0x2D, 0x7A, 0x7F, 0x61, 0x50, 0x22, 0x11, 0x06, 0x47, 0x16, 0x52, 0x4E,
0x71, 0x3E, 0x69, 0x43, 0x34, 0x5C, 0x58, 0x7D };

static const uint16_t MISTY1_SBOX_S9[512] = {
alignas(64) static const uint16_t MISTY1_SBOX_S9[512] = {
0x01C3, 0x00CB, 0x0153, 0x019F, 0x01E3, 0x00E9, 0x00FB, 0x0035, 0x0181,
0x00B9, 0x0117, 0x01EB, 0x0133, 0x0009, 0x002D, 0x00D3, 0x00C7, 0x014A,
0x0037, 0x007E, 0x00EB, 0x0164, 0x0193, 0x01D8, 0x00A3, 0x011E, 0x0055,
Expand Down
8 changes: 4 additions & 4 deletions src/lib/block/seed/seed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Botan {

namespace {

const uint32_t SEED_S0[256] = {
alignas(64) const uint32_t SEED_S0[256] = {
0x2989A1A8, 0x05858184, 0x16C6D2D4, 0x13C3D3D0, 0x14445054, 0x1D0D111C,
0x2C8CA0AC, 0x25052124, 0x1D4D515C, 0x03434340, 0x18081018, 0x1E0E121C,
0x11415150, 0x3CCCF0FC, 0x0ACAC2C8, 0x23436360, 0x28082028, 0x04444044,
Expand Down Expand Up @@ -57,7 +57,7 @@ const uint32_t SEED_S0[256] = {
0x07070304, 0x33033330, 0x28C8E0E8, 0x1B0B1318, 0x05050104, 0x39497178,
0x10809090, 0x2A4A6268, 0x2A0A2228, 0x1A8A9298 };

const uint32_t SEED_S1[256] = {
alignas(64) const uint32_t SEED_S1[256] = {
0x38380830, 0xE828C8E0, 0x2C2D0D21, 0xA42686A2, 0xCC0FCFC3, 0xDC1ECED2,
0xB03383B3, 0xB83888B0, 0xAC2F8FA3, 0x60204060, 0x54154551, 0xC407C7C3,
0x44044440, 0x6C2F4F63, 0x682B4B63, 0x581B4B53, 0xC003C3C3, 0x60224262,
Expand Down Expand Up @@ -102,7 +102,7 @@ const uint32_t SEED_S1[256] = {
0x080A0A02, 0x84078783, 0xD819C9D1, 0x4C0C4C40, 0x80038383, 0x8C0F8F83,
0xCC0ECEC2, 0x383B0B33, 0x480A4A42, 0xB43787B3 };

const uint32_t SEED_S2[256] = {
alignas(64) const uint32_t SEED_S2[256] = {
0xA1A82989, 0x81840585, 0xD2D416C6, 0xD3D013C3, 0x50541444, 0x111C1D0D,
0xA0AC2C8C, 0x21242505, 0x515C1D4D, 0x43400343, 0x10181808, 0x121C1E0E,
0x51501141, 0xF0FC3CCC, 0xC2C80ACA, 0x63602343, 0x20282808, 0x40440444,
Expand Down Expand Up @@ -147,7 +147,7 @@ const uint32_t SEED_S2[256] = {
0x03040707, 0x33303303, 0xE0E828C8, 0x13181B0B, 0x01040505, 0x71783949,
0x90901080, 0x62682A4A, 0x22282A0A, 0x92981A8A };

const uint32_t SEED_S3[256] = {
alignas(64) const uint32_t SEED_S3[256] = {
0x08303838, 0xC8E0E828, 0x0D212C2D, 0x86A2A426, 0xCFC3CC0F, 0xCED2DC1E,
0x83B3B033, 0x88B0B838, 0x8FA3AC2F, 0x40606020, 0x45515415, 0xC7C3C407,
0x44404404, 0x4F636C2F, 0x4B63682B, 0x4B53581B, 0xC3C3C003, 0x42626022,
Expand Down
18 changes: 9 additions & 9 deletions src/lib/block/twofish/twofish_tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Botan {

const uint8_t Twofish::Q0[256] = {
alignas(64) const uint8_t Twofish::Q0[256] = {
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
Expand All @@ -33,7 +33,7 @@ const uint8_t Twofish::Q0[256] = {
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
0x4A, 0x5E, 0xC1, 0xE0 };

const uint8_t Twofish::Q1[256] = {
alignas(64) const uint8_t Twofish::Q1[256] = {
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
Expand All @@ -57,12 +57,12 @@ const uint8_t Twofish::Q1[256] = {
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
0x55, 0x09, 0xBE, 0x91 };

const uint8_t Twofish::RS[32] = {
alignas(64) const uint8_t Twofish::RS[32] = {
0x01, 0xA4, 0x02, 0xA4, 0xA4, 0x56, 0xA1, 0x55, 0x55, 0x82, 0xFC, 0x87,
0x87, 0xF3, 0xC1, 0x5A, 0x5A, 0x1E, 0x47, 0x58, 0x58, 0xC6, 0xAE, 0xDB,
0xDB, 0x68, 0x3D, 0x9E, 0x9E, 0xE5, 0x19, 0x03 };

const uint8_t Twofish::EXP_TO_POLY[255] = {
alignas(64) const uint8_t Twofish::EXP_TO_POLY[255] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
Expand All @@ -86,7 +86,7 @@ const uint8_t Twofish::EXP_TO_POLY[255] = {
0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
0x8F, 0x53, 0xA6 };

const uint8_t Twofish::POLY_TO_EXP[255] = {
alignas(64) const uint8_t Twofish::POLY_TO_EXP[255] = {
0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
Expand All @@ -110,7 +110,7 @@ const uint8_t Twofish::POLY_TO_EXP[255] = {
0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
0x85, 0xC8, 0xA1 };

const uint32_t Twofish::MDS0[256] = {
alignas(64) const uint32_t Twofish::MDS0[256] = {
0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
Expand Down Expand Up @@ -155,7 +155,7 @@ const uint32_t Twofish::MDS0[256] = {
0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 };

const uint32_t Twofish::MDS1[256] = {
alignas(64) const uint32_t Twofish::MDS1[256] = {
0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
Expand Down Expand Up @@ -200,7 +200,7 @@ const uint32_t Twofish::MDS1[256] = {
0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 };

const uint32_t Twofish::MDS2[256] = {
alignas(64) const uint32_t Twofish::MDS2[256] = {
0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
Expand Down Expand Up @@ -245,7 +245,7 @@ const uint32_t Twofish::MDS2[256] = {
0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF };

const uint32_t Twofish::MDS3[256] = {
alignas(64) const uint32_t Twofish::MDS3[256] = {
0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
Expand Down
167 changes: 88 additions & 79 deletions src/lib/codec/base32/base32.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*
* Base32 Encoding and Decoding
* (C) 2018 Erwan Chaussy
* (C) 2018 Jack Lloyd
* (C) 2018,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/base32.h>
#include <botan/internal/codec_base.h>
#include <botan/internal/rounding.h>
#include <botan/internal/ct_utils.h>

namespace Botan {

Expand Down Expand Up @@ -58,45 +59,11 @@ class Base32 final
return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;
}

static void encode(char out[8], const uint8_t in[5]) noexcept
{
out[0] = Base32::m_bin_to_base32[(in[0] & 0xF8) >> 3];
out[1] = Base32::m_bin_to_base32[((in[0] & 0x07) << 2) | (in[1] >> 6)];
out[2] = Base32::m_bin_to_base32[((in[1] & 0x3E) >> 1)];
out[3] = Base32::m_bin_to_base32[((in[1] & 0x01) << 4) | (in[2] >> 4)];
out[4] = Base32::m_bin_to_base32[((in[2] & 0x0F) << 1) | (in[3] >> 7)];
out[5] = Base32::m_bin_to_base32[((in[3] & 0x7C) >> 2)];
out[6] = Base32::m_bin_to_base32[((in[3] & 0x03) << 3) | (in[4] >> 5)];
out[7] = Base32::m_bin_to_base32[in[4] & 0x1F];
}
static void encode(char out[8], const uint8_t in[5]) noexcept;

static inline uint8_t lookup_binary_value(char input) noexcept
{
return Base32::m_base32_to_bin[static_cast<uint8_t>(input)];
}
static uint8_t lookup_binary_value(char input) noexcept;

static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)
{
if(bin <= 0x1F)
{
return true;
}
else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
{
std::string bad_char(1, input);
if(bad_char == "\t")
{ bad_char = "\\t"; }
else if(bad_char == "\n")
{ bad_char = "\\n"; }
else if(bad_char == "\r")
{ bad_char = "\\r"; }

throw Invalid_Argument(
std::string("base32_decode: invalid base32 character '") +
bad_char + "'");
}
return false;
}
static bool check_bad_char(uint8_t bin, char input, bool ignore_ws);

static void decode(uint8_t* out_ptr, const uint8_t decode_buf[8])
{
Expand All @@ -116,55 +83,97 @@ class Base32 final
static const size_t m_encoding_bits = 5;
static const size_t m_remaining_bits_before_padding = 6;


static const size_t m_encoding_bytes_in = 5;
static const size_t m_encoding_bytes_out = 8;
};

namespace {

static const uint8_t m_bin_to_base32[32];
static const uint8_t m_base32_to_bin[256];
};
char lookup_base32_char(uint8_t x)
{
BOTAN_DEBUG_ASSERT(x < 32);

const auto in_AZ = CT::Mask<uint8_t>::is_lt(x, 26);

const char c_AZ = 'A' + x;
const char c_27 = '2' + (x - 26);

return in_AZ.select(c_AZ, c_27);
}

}

const uint8_t Base32::m_bin_to_base32[32] =
//static
void Base32::encode(char out[8], const uint8_t in[5]) noexcept
{
'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',
'2', '3', '4', '5', '6', '7'
};
const uint8_t b0 = (in[0] & 0xF8) >> 3;
const uint8_t b1 = ((in[0] & 0x07) << 2) | (in[1] >> 6);
const uint8_t b2 = ((in[1] & 0x3E) >> 1);
const uint8_t b3 = ((in[1] & 0x01) << 4) | (in[2] >> 4);
const uint8_t b4 = ((in[2] & 0x0F) << 1) | (in[3] >> 7);
const uint8_t b5 = ((in[3] & 0x7C) >> 2);
const uint8_t b6 = ((in[3] & 0x03) << 3) | (in[4] >> 5);
const uint8_t b7 = in[4] & 0x1F;

out[0] = lookup_base32_char(b0);
out[1] = lookup_base32_char(b1);
out[2] = lookup_base32_char(b2);
out[3] = lookup_base32_char(b3);
out[4] = lookup_base32_char(b4);
out[5] = lookup_base32_char(b5);
out[6] = lookup_base32_char(b6);
out[7] = lookup_base32_char(b7);
}

/*
* base32 Decoder Lookup Table
* Warning: assumes ASCII encodings
*/
const uint8_t Base32::m_base32_to_bin[256] =
//static
uint8_t Base32::lookup_binary_value(char input) noexcept
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
const uint8_t c = static_cast<uint8_t>(input);

const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('Z'));
const auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, uint8_t('2'), uint8_t('7'));

const auto is_equal = CT::Mask<uint8_t>::is_equal(c, uint8_t('='));
const auto is_whitespace = CT::Mask<uint8_t>::is_any_of(c, {
uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')
});

const uint8_t c_upper = c - uint8_t('A');
const uint8_t c_decim = c - uint8_t('2') + 26;

uint8_t ret = 0xFF; // default value

ret = is_alpha_upper.select(c_upper, ret);
ret = is_decimal.select(c_decim, ret);
ret = is_equal.select(0x81, ret);
ret = is_whitespace.select(0x80, ret);

return ret;
}

//static
bool Base32::check_bad_char(uint8_t bin, char input, bool ignore_ws)
{
if(bin <= 0x1F)
{
return true;
}
else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
{
std::string bad_char(1, input);
if(bad_char == "\t")
{ bad_char = "\\t"; }
else if(bad_char == "\n")
{ bad_char = "\\n"; }
else if(bad_char == "\r")
{ bad_char = "\\r"; }

throw Invalid_Argument(
std::string("base32_decode: invalid base32 character '") +
bad_char + "'");
}
return false;
}

}

Expand Down
129 changes: 70 additions & 59 deletions src/lib/codec/base58/base58.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) 2018 Jack Lloyd
* (C) 2018,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
Expand All @@ -9,6 +9,7 @@
#include <botan/bigint.h>
#include <botan/divide.h>
#include <botan/loadstor.h>
#include <botan/internal/ct_utils.h>
#include <botan/hash.h>

namespace Botan {
Expand All @@ -30,73 +31,52 @@ uint32_t sha256_d_checksum(const uint8_t input[], size_t input_length)
return load_be<uint32_t>(checksum.data(), 0);
}

class Character_Table
char lookup_base58_char(uint8_t x)
{
public:
// This must be a literal constant
Character_Table(const char* alphabet) :
m_alphabet(alphabet)
{
const size_t alpha_len = std::strlen(alphabet);

// 128 or up would flow into 0x80 invalid bit
if(alpha_len == 0 || alpha_len >= 128)
throw Invalid_Argument("Bad Character_Table string");

m_alphabet_len = static_cast<uint8_t>(alpha_len);

set_mem(m_tab, 256, 0x80);

for(size_t i = 0; m_alphabet[i]; ++i)
{
const uint8_t b = static_cast<uint8_t>(m_alphabet[i]);
BOTAN_ASSERT(m_tab[b] == 0x80, "No duplicate chars");
m_tab[b] = static_cast<uint8_t>(i);
}
}

uint8_t radix() const { return m_alphabet_len; }

char operator[](size_t i) const
{
BOTAN_ASSERT(i < m_alphabet_len, "Character in range");
return m_alphabet[i];
}

uint8_t code_for(char c) const
{
return m_tab[static_cast<uint8_t>(c)];
}

private:
const char* m_alphabet;
uint8_t m_alphabet_len;
uint8_t m_tab[256];
};

static const Character_Table& BASE58_ALPHA()
{
static const Character_Table base58_alpha("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
return base58_alpha;
// "123456789 ABCDEFGH JKLMN PQRSTUVWXYZ abcdefghijk mnopqrstuvwxyz"
BOTAN_DEBUG_ASSERT(x < 58);

const auto is_dec_19 = CT::Mask<uint8_t>::is_lte(x, 8);
const auto is_alpha_AH = CT::Mask<uint8_t>::is_within_range(x, 9, 16);
const auto is_alpha_JN = CT::Mask<uint8_t>::is_within_range(x, 17, 21);
const auto is_alpha_PZ = CT::Mask<uint8_t>::is_within_range(x, 22, 32);
const auto is_alpha_ak = CT::Mask<uint8_t>::is_within_range(x, 33, 43);
// otherwise in 'm'-'z'

const char c_19 = '1' + x;
const char c_AH = 'A' + (x - 9);
const char c_JN = 'J' + (x - 17);
const char c_PZ = 'P' + (x - 22);
const char c_ak = 'a' + (x - 33);
const char c_mz = 'm' + (x - 44);

char ret = c_mz;
ret = is_dec_19.select(c_19, ret);
ret = is_alpha_AH.select(c_AH, ret);
ret = is_alpha_JN.select(c_JN, ret);
ret = is_alpha_PZ.select(c_PZ, ret);
ret = is_alpha_ak.select(c_ak, ret);

return ret;
}

std::string base58_encode(BigInt v, size_t leading_zeros)
{
const auto base58 = BASE58_ALPHA();
const uint8_t radix = 58;

std::string result;
BigInt q;
uint8_t r;

while(v.is_nonzero())
{
ct_divide_u8(v, base58.radix(), q, r);
result.push_back(base58[r]);
uint8_t r;
ct_divide_u8(v, radix, q, r);
result.push_back(lookup_base58_char(r));
v.swap(q);
}

for(size_t i = 0; i != leading_zeros; ++i)
result.push_back(base58[0]);
result.push_back('1'); // 'zero' byte

return std::string(result.rbegin(), result.rend());
}
Expand All @@ -112,6 +92,39 @@ size_t count_leading_zeros(const T input[], size_t input_length, Z zero)
return leading_zeros;
}

uint8_t base58_value_of(char input)
{
// "123456789 ABCDEFGH JKLMN PQRSTUVWXYZ abcdefghijk mnopqrstuvwxyz"

const uint8_t c = static_cast<uint8_t>(input);

const auto is_dec_19 = CT::Mask<uint8_t>::is_within_range(c, uint8_t('1'), uint8_t('9'));
const auto is_alpha_AH = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('H'));
const auto is_alpha_JN = CT::Mask<uint8_t>::is_within_range(c, uint8_t('J'), uint8_t('N'));
const auto is_alpha_PZ = CT::Mask<uint8_t>::is_within_range(c, uint8_t('P'), uint8_t('Z'));

const auto is_alpha_ak = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('k'));
const auto is_alpha_mz = CT::Mask<uint8_t>::is_within_range(c, uint8_t('m'), uint8_t('z'));

const uint8_t c_dec_19 = c - uint8_t('1');
const uint8_t c_AH = c - uint8_t('A') + 9;
const uint8_t c_JN = c - uint8_t('J') + 17;
const uint8_t c_PZ = c - uint8_t('P') + 22;

const uint8_t c_ak = c - uint8_t('a') + 33;
const uint8_t c_mz = c - uint8_t('m') + 44;

uint8_t ret = 0xFF; // default value

ret = is_dec_19.select(c_dec_19, ret);
ret = is_alpha_AH.select(c_AH, ret);
ret = is_alpha_JN.select(c_JN, ret);
ret = is_alpha_PZ.select(c_PZ, ret);
ret = is_alpha_ak.select(c_ak, ret);
ret = is_alpha_mz.select(c_mz, ret);
return ret;
}

}

std::string base58_encode(const uint8_t input[], size_t input_length)
Expand All @@ -130,9 +143,7 @@ std::string base58_check_encode(const uint8_t input[], size_t input_length)

std::vector<uint8_t> base58_decode(const char input[], size_t input_length)
{
const auto base58 = BASE58_ALPHA();

const size_t leading_zeros = count_leading_zeros(input, input_length, base58[0]);
const size_t leading_zeros = count_leading_zeros(input, input_length, '1');

BigInt v;

Expand All @@ -143,12 +154,12 @@ std::vector<uint8_t> base58_decode(const char input[], size_t input_length)
if(c == ' ' || c == '\n')
continue;

const size_t idx = base58.code_for(c);
const uint8_t idx = base58_value_of(c);

if(idx == 0x80)
if(idx == 0xFF)
throw Decoding_Error("Invalid base58");

v *= base58.radix();
v *= 58;
v += idx;
}

Expand Down
173 changes: 96 additions & 77 deletions src/lib/codec/base64/base64.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Base64 Encoding and Decoding
* (C) 2010,2015 Jack Lloyd
* (C) 2010,2015,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
Expand All @@ -9,6 +9,7 @@
#include <botan/internal/codec_base.h>
#include <botan/exceptn.h>
#include <botan/internal/rounding.h>
#include <botan/internal/ct_utils.h>

namespace Botan {

Expand Down Expand Up @@ -58,41 +59,11 @@ class Base64 final
return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;
}

static void encode(char out[8], const uint8_t in[5]) noexcept
{
out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2];
out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
out[3] = Base64::m_bin_to_base64[in[2] & 0x3F];
}
static void encode(char out[8], const uint8_t in[5]) noexcept;

static inline uint8_t lookup_binary_value(char input) noexcept
{
return Base64::m_base64_to_bin[static_cast<uint8_t>(input)];
}
static uint8_t lookup_binary_value(char input) noexcept;

static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)
{
if(bin <= 0x3F)
{
return true;
}
else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
{
std::string bad_char(1, input);
if(bad_char == "\t")
{ bad_char = "\\t"; }
else if(bad_char == "\n")
{ bad_char = "\\n"; }
else if(bad_char == "\r")
{ bad_char = "\\r"; }

throw Invalid_Argument(
std::string("base64_decode: invalid base64 character '") +
bad_char + "'");
}
return false;
}
static bool check_bad_char(uint8_t bin, char input, bool ignore_ws);

static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4])
{
Expand All @@ -110,57 +81,105 @@ class Base64 final
static const size_t m_encoding_bits = 6;
static const size_t m_remaining_bits_before_padding = 8;


static const size_t m_encoding_bytes_in = 3;
static const size_t m_encoding_bytes_out = 4;
};

char lookup_base64_char(uint8_t x)
{
BOTAN_DEBUG_ASSERT(x < 64);

const auto in_az = CT::Mask<uint8_t>::is_within_range(x, 26, 51);
const auto in_09 = CT::Mask<uint8_t>::is_within_range(x, 52, 61);
const auto eq_plus = CT::Mask<uint8_t>::is_equal(x, 62);
const auto eq_slash = CT::Mask<uint8_t>::is_equal(x, 63);

const char c_AZ = 'A' + x;
const char c_az = 'a' + (x - 26);
const char c_09 = '0' + (x - 2*26);
const char c_plus = '+';
const char c_slash = '/';

char ret = c_AZ;
ret = in_az.select(c_az, ret);
ret = in_09.select(c_09, ret);
ret = eq_plus.select(c_plus, ret);
ret = eq_slash.select(c_slash, ret);

return ret;
}

static const uint8_t m_bin_to_base64[64];
static const uint8_t m_base64_to_bin[256];
};
//static
void Base64::encode(char out[8], const uint8_t in[5]) noexcept
{
const uint8_t b0 = (in[0] & 0xFC) >> 2;
const uint8_t b1 = ((in[0] & 0x03) << 4) | (in[1] >> 4);
const uint8_t b2 = ((in[1] & 0x0F) << 2) | (in[2] >> 6);
const uint8_t b3 = in[2] & 0x3F;
out[0] = lookup_base64_char(b0);
out[1] = lookup_base64_char(b1);
out[2] = lookup_base64_char(b2);
out[3] = lookup_base64_char(b3);
}

const uint8_t Base64::m_bin_to_base64[64] =
//static
uint8_t Base64::lookup_binary_value(char input) noexcept
{
'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', '+', '/'
};
const uint8_t c = static_cast<uint8_t>(input);

/*
* base64 Decoder Lookup Table
* Warning: assumes ASCII encodings
*/
const uint8_t Base64::m_base64_to_bin[256] =
const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('Z'));
const auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('z'));
const auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, uint8_t('0'), uint8_t('9'));

const auto is_plus = CT::Mask<uint8_t>::is_equal(c, uint8_t('+'));
const auto is_slash = CT::Mask<uint8_t>::is_equal(c, uint8_t('/'));
const auto is_equal = CT::Mask<uint8_t>::is_equal(c, uint8_t('='));

const auto is_whitespace = CT::Mask<uint8_t>::is_any_of(c, {
uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')
});

const uint8_t c_upper = c - uint8_t('A');
const uint8_t c_lower = c - uint8_t('a') + 26;
const uint8_t c_decim = c - uint8_t('0') + 2*26;

uint8_t ret = 0xFF; // default value

ret = is_alpha_upper.select(c_upper, ret);
ret = is_alpha_lower.select(c_lower, ret);
ret = is_decimal.select(c_decim, ret);
ret = is_plus.select(62, ret);
ret = is_slash.select(63, ret);
ret = is_equal.select(0x81, ret);
ret = is_whitespace.select(0x80, ret);

return ret;
}

//static
bool Base64::check_bad_char(uint8_t bin, char input, bool ignore_ws)
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
if(bin <= 0x3F)
{
return true;
}
else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
{
std::string bad_char(1, input);
if(bad_char == "\t")
{ bad_char = "\\t"; }
else if(bad_char == "\n")
{ bad_char = "\\n"; }
else if(bad_char == "\r")
{ bad_char = "\\r"; }

throw Invalid_Argument(
std::string("base64_decode: invalid base64 character '") +
bad_char + "'");
}
return false;
}

}

size_t base64_encode(char out[],
Expand Down
107 changes: 55 additions & 52 deletions src/lib/codec/hex/hex.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
/*
* Hex Encoding and Decoding
* (C) 2010 Jack Lloyd
* (C) 2010,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/hex.h>
#include <botan/mem_ops.h>
#include <botan/exceptn.h>
#include <botan/internal/ct_utils.h>

namespace Botan {

namespace {

char hex_encode_nibble(uint8_t n, bool uppercase)
{
BOTAN_DEBUG_ASSERT(n <= 15);

const auto in_09 = CT::Mask<uint8_t>::is_lt(n, 10);

const char c_09 = n + '0';
const char c_af = n + (uppercase ? 'A' : 'a') - 10;

return in_09.select(c_09, c_af);
}

}

void hex_encode(char output[],
const uint8_t input[],
size_t input_length,
bool uppercase)
{
static const uint8_t BIN_TO_HEX_UPPER[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };

static const uint8_t BIN_TO_HEX_LOWER[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };

const uint8_t* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER;

for(size_t i = 0; i != input_length; ++i)
{
uint8_t x = input[i];
output[2*i ] = tbl[(x >> 4) & 0x0F];
output[2*i+1] = tbl[(x ) & 0x0F];
const uint8_t n0 = (input[i] >> 4) & 0xF;
const uint8_t n1 = (input[i] ) & 0xF;

output[2*i ] = hex_encode_nibble(n0, uppercase);
output[2*i+1] = hex_encode_nibble(n1, uppercase);
}
}

Expand All @@ -46,57 +55,51 @@ std::string hex_encode(const uint8_t input[],
return output;
}

namespace {

uint8_t hex_char_to_bin(char input)
{
const uint8_t c = static_cast<uint8_t>(input);

const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('F'));
const auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('f'));
const auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, uint8_t('0'), uint8_t('9'));

const auto is_whitespace = CT::Mask<uint8_t>::is_any_of(c, {
uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')
});

const uint8_t c_upper = c - uint8_t('A') + 10;
const uint8_t c_lower = c - uint8_t('a') + 10;
const uint8_t c_decim = c - uint8_t('0');

uint8_t ret = 0xFF; // default value

ret = is_alpha_upper.select(c_upper, ret);
ret = is_alpha_lower.select(c_lower, ret);
ret = is_decimal.select(c_decim, ret);
ret = is_whitespace.select(0x80, ret);

return ret;
}

}


size_t hex_decode(uint8_t output[],
const char input[],
size_t input_length,
size_t& input_consumed,
bool ignore_ws)
{
/*
* Mapping of hex characters to either their binary equivalent
* or to an error code.
* If valid hex (0-9 A-F a-f), the value.
* If whitespace, then 0x80
* Otherwise 0xFF
* Warning: this table assumes ASCII character encodings
*/

static const uint8_t HEX_TO_BIN[256] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

uint8_t* out_ptr = output;
bool top_nibble = true;

clear_mem(output, input_length / 2);

for(size_t i = 0; i != input_length; ++i)
{
const uint8_t bin = HEX_TO_BIN[static_cast<uint8_t>(input[i])];
const uint8_t bin = hex_char_to_bin(input[i]);

if(bin >= 0x10)
{
Expand Down
8 changes: 4 additions & 4 deletions src/lib/hash/checksum/crc24/crc24.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Botan {

namespace {

const uint32_t CRC24_T0[256] = {
alignas(64) const uint32_t CRC24_T0[256] = {
0x00000000, 0x00FB4C86, 0x000DD58A, 0x00F6990C, 0x00E1E693, 0x001AAA15, 0x00EC3319,
0x00177F9F, 0x003981A1, 0x00C2CD27, 0x0034542B, 0x00CF18AD, 0x00D86732, 0x00232BB4,
0x00D5B2B8, 0x002EFE3E, 0x00894EC5, 0x00720243, 0x00849B4F, 0x007FD7C9, 0x0068A856,
Expand Down Expand Up @@ -53,7 +53,7 @@ const uint32_t CRC24_T0[256] = {
0x000CD1F6, 0x00FA48FA, 0x0001047C, 0x002FFA42, 0x00D4B6C4, 0x00222FC8, 0x00D9634E,
0x00CE1CD1, 0x00355057, 0x00C3C95B, 0x003885DD };

const uint32_t CRC24_T1[256] = {
alignas(64) const uint32_t CRC24_T1[256] = {
0x00000000, 0x00488F66, 0x00901ECD, 0x00D891AB, 0x00DB711C, 0x0093FE7A, 0x004B6FD1,
0x0003E0B7, 0x00B6E338, 0x00FE6C5E, 0x0026FDF5, 0x006E7293, 0x006D9224, 0x00251D42,
0x00FD8CE9, 0x00B5038F, 0x006CC771, 0x00244817, 0x00FCD9BC, 0x00B456DA, 0x00B7B66D,
Expand Down Expand Up @@ -92,7 +92,7 @@ const uint32_t CRC24_T1[256] = {
0x00FA442B, 0x0022D580, 0x006A5AE6, 0x00DF5969, 0x0097D60F, 0x004F47A4, 0x0007C8C2,
0x00042875, 0x004CA713, 0x009436B8, 0x00DCB9DE };

const uint32_t CRC24_T2[256] = {
alignas(64) const uint32_t CRC24_T2[256] = {
0x00000000, 0x00D70983, 0x00555F80, 0x00825603, 0x0051F286, 0x0086FB05, 0x0004AD06,
0x00D3A485, 0x0059A88B, 0x008EA108, 0x000CF70B, 0x00DBFE88, 0x00085A0D, 0x00DF538E,
0x005D058D, 0x008A0C0E, 0x00491C91, 0x009E1512, 0x001C4311, 0x00CB4A92, 0x0018EE17,
Expand Down Expand Up @@ -131,7 +131,7 @@ const uint32_t CRC24_T2[256] = {
0x002633E5, 0x00A465E6, 0x00736C65, 0x00F9606B, 0x002E69E8, 0x00AC3FEB, 0x007B3668,
0x00A892ED, 0x007F9B6E, 0x00FDCD6D, 0x002AC4EE };

const uint32_t CRC24_T3[256] = {
alignas(64) const uint32_t CRC24_T3[256] = {
0x00000000, 0x00520936, 0x00A4126C, 0x00F61B5A, 0x004825D8, 0x001A2CEE, 0x00EC37B4,
0x00BE3E82, 0x006B0636, 0x00390F00, 0x00CF145A, 0x009D1D6C, 0x002323EE, 0x00712AD8,
0x00873182, 0x00D538B4, 0x00D60C6C, 0x0084055A, 0x00721E00, 0x00201736, 0x009E29B4,
Expand Down
128 changes: 66 additions & 62 deletions src/lib/hash/checksum/crc32/crc32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,81 +15,85 @@ std::unique_ptr<HashFunction> CRC32::copy_state() const
return std::unique_ptr<HashFunction>(new CRC32(*this));
}

namespace {

const uint32_t CRC32_T0[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };

}

/*
* Update a CRC32 Checksum
*/
void CRC32::add_data(const uint8_t input[], size_t length)
{
const uint32_t TABLE[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };

uint32_t tmp = m_crc;
while(length >= 16)
{
tmp = TABLE[(tmp ^ input[ 0]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 1]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 2]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 3]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 4]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 5]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 6]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 7]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 8]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[ 9]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[10]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[11]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[12]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[13]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[14]) & 0xFF] ^ (tmp >> 8);
tmp = TABLE[(tmp ^ input[15]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 0]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 1]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 2]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 3]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 4]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 5]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 6]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 7]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 8]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[ 9]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[10]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[11]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[12]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[13]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[14]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[15]) & 0xFF] ^ (tmp >> 8);
input += 16;
length -= 16;
}

for(size_t i = 0; i != length; ++i)
tmp = TABLE[(tmp ^ input[i]) & 0xFF] ^ (tmp >> 8);
tmp = CRC32_T0[(tmp ^ input[i]) & 0xFF] ^ (tmp >> 8);

m_crc = tmp;
}
Expand Down
16 changes: 8 additions & 8 deletions src/lib/hash/whirlpool/whrl_tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Botan {

const uint64_t Whirlpool::C0[256] = {
alignas(64) const uint64_t Whirlpool::C0[256] = {
0x18186018C07830D8, 0x23238C2305AF4626, 0xC6C63FC67EF991B8, 0xE8E887E8136FCDFB,
0x878726874CA113CB, 0xB8B8DAB8A9626D11, 0x0101040108050209, 0x4F4F214F426E9E0D,
0x3636D836ADEE6C9B, 0xA6A6A2A6590451FF, 0xD2D26FD2DEBDB90C, 0xF5F5F3F5FB06F70E,
Expand Down Expand Up @@ -75,7 +75,7 @@ const uint64_t Whirlpool::C0[256] = {
0xCCCC17CC2EDB85E2, 0x424215422A578468, 0x98985A98B4C22D2C, 0xA4A4AAA4490E55ED,
0x2828A0285D885075, 0x5C5C6D5CDA31B886, 0xF8F8C7F8933FED6B, 0x8686228644A411C2 };

const uint64_t Whirlpool::C1[256] = {
alignas(64) const uint64_t Whirlpool::C1[256] = {
0xD818186018C07830, 0x2623238C2305AF46, 0xB8C6C63FC67EF991, 0xFBE8E887E8136FCD,
0xCB878726874CA113, 0x11B8B8DAB8A9626D, 0x0901010401080502, 0x0D4F4F214F426E9E,
0x9B3636D836ADEE6C, 0xFFA6A6A2A6590451, 0x0CD2D26FD2DEBDB9, 0x0EF5F5F3F5FB06F7,
Expand Down Expand Up @@ -141,7 +141,7 @@ const uint64_t Whirlpool::C1[256] = {
0xE2CCCC17CC2EDB85, 0x68424215422A5784, 0x2C98985A98B4C22D, 0xEDA4A4AAA4490E55,
0x752828A0285D8850, 0x865C5C6D5CDA31B8, 0x6BF8F8C7F8933FED, 0xC28686228644A411 };

const uint64_t Whirlpool::C2[256] = {
alignas(64) const uint64_t Whirlpool::C2[256] = {
0x30D818186018C078, 0x462623238C2305AF, 0x91B8C6C63FC67EF9, 0xCDFBE8E887E8136F,
0x13CB878726874CA1, 0x6D11B8B8DAB8A962, 0x0209010104010805, 0x9E0D4F4F214F426E,
0x6C9B3636D836ADEE, 0x51FFA6A6A2A65904, 0xB90CD2D26FD2DEBD, 0xF70EF5F5F3F5FB06,
Expand Down Expand Up @@ -207,7 +207,7 @@ const uint64_t Whirlpool::C2[256] = {
0x85E2CCCC17CC2EDB, 0x8468424215422A57, 0x2D2C98985A98B4C2, 0x55EDA4A4AAA4490E,
0x50752828A0285D88, 0xB8865C5C6D5CDA31, 0xED6BF8F8C7F8933F, 0x11C28686228644A4 };

const uint64_t Whirlpool::C3[256] = {
alignas(64) const uint64_t Whirlpool::C3[256] = {
0x7830D818186018C0, 0xAF462623238C2305, 0xF991B8C6C63FC67E, 0x6FCDFBE8E887E813,
0xA113CB878726874C, 0x626D11B8B8DAB8A9, 0x0502090101040108, 0x6E9E0D4F4F214F42,
0xEE6C9B3636D836AD, 0x0451FFA6A6A2A659, 0xBDB90CD2D26FD2DE, 0x06F70EF5F5F3F5FB,
Expand Down Expand Up @@ -273,7 +273,7 @@ const uint64_t Whirlpool::C3[256] = {
0xDB85E2CCCC17CC2E, 0x578468424215422A, 0xC22D2C98985A98B4, 0x0E55EDA4A4AAA449,
0x8850752828A0285D, 0x31B8865C5C6D5CDA, 0x3FED6BF8F8C7F893, 0xA411C28686228644 };

const uint64_t Whirlpool::C4[256] = {
alignas(64) const uint64_t Whirlpool::C4[256] = {
0xC07830D818186018, 0x05AF462623238C23, 0x7EF991B8C6C63FC6, 0x136FCDFBE8E887E8,
0x4CA113CB87872687, 0xA9626D11B8B8DAB8, 0x0805020901010401, 0x426E9E0D4F4F214F,
0xADEE6C9B3636D836, 0x590451FFA6A6A2A6, 0xDEBDB90CD2D26FD2, 0xFB06F70EF5F5F3F5,
Expand Down Expand Up @@ -339,7 +339,7 @@ const uint64_t Whirlpool::C4[256] = {
0x2EDB85E2CCCC17CC, 0x2A57846842421542, 0xB4C22D2C98985A98, 0x490E55EDA4A4AAA4,
0x5D8850752828A028, 0xDA31B8865C5C6D5C, 0x933FED6BF8F8C7F8, 0x44A411C286862286 };

const uint64_t Whirlpool::C5[256] = {
alignas(64) const uint64_t Whirlpool::C5[256] = {
0x18C07830D8181860, 0x2305AF462623238C, 0xC67EF991B8C6C63F, 0xE8136FCDFBE8E887,
0x874CA113CB878726, 0xB8A9626D11B8B8DA, 0x0108050209010104, 0x4F426E9E0D4F4F21,
0x36ADEE6C9B3636D8, 0xA6590451FFA6A6A2, 0xD2DEBDB90CD2D26F, 0xF5FB06F70EF5F5F3,
Expand Down Expand Up @@ -405,7 +405,7 @@ const uint64_t Whirlpool::C5[256] = {
0xCC2EDB85E2CCCC17, 0x422A578468424215, 0x98B4C22D2C98985A, 0xA4490E55EDA4A4AA,
0x285D8850752828A0, 0x5CDA31B8865C5C6D, 0xF8933FED6BF8F8C7, 0x8644A411C2868622 };

const uint64_t Whirlpool::C6[256] = {
alignas(64) const uint64_t Whirlpool::C6[256] = {
0x6018C07830D81818, 0x8C2305AF46262323, 0x3FC67EF991B8C6C6, 0x87E8136FCDFBE8E8,
0x26874CA113CB8787, 0xDAB8A9626D11B8B8, 0x0401080502090101, 0x214F426E9E0D4F4F,
0xD836ADEE6C9B3636, 0xA2A6590451FFA6A6, 0x6FD2DEBDB90CD2D2, 0xF3F5FB06F70EF5F5,
Expand Down Expand Up @@ -471,7 +471,7 @@ const uint64_t Whirlpool::C6[256] = {
0x17CC2EDB85E2CCCC, 0x15422A5784684242, 0x5A98B4C22D2C9898, 0xAAA4490E55EDA4A4,
0xA0285D8850752828, 0x6D5CDA31B8865C5C, 0xC7F8933FED6BF8F8, 0x228644A411C28686 };

const uint64_t Whirlpool::C7[256] = {
alignas(64) const uint64_t Whirlpool::C7[256] = {
0x186018C07830D818, 0x238C2305AF462623, 0xC63FC67EF991B8C6, 0xE887E8136FCDFBE8,
0x8726874CA113CB87, 0xB8DAB8A9626D11B8, 0x0104010805020901, 0x4F214F426E9E0D4F,
0x36D836ADEE6C9B36, 0xA6A2A6590451FFA6, 0xD26FD2DEBDB90CD2, 0xF5F3F5FB06F70EF5,
Expand Down
24 changes: 24 additions & 0 deletions src/lib/utils/ct_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,30 @@ class Mask
return ~Mask<T>::is_lt(x, y);
}

static Mask<T> is_within_range(T v, T l, T u)
{
//return Mask<T>::is_gte(v, l) & Mask<T>::is_lte(v, u);

const T v_lt_l = v^((v^l) | ((v-l)^v));
const T v_gt_u = u^((u^v) | ((u-v)^u));
const T either = v_lt_l | v_gt_u;
return ~Mask<T>(expand_top_bit(either));
}

static Mask<T> is_any_of(T v, std::initializer_list<T> accepted)
{
T accept = 0;

for(auto a: accepted)
{
const T diff = a ^ v;
const T eq_zero = ~diff & (diff - 1);
accept |= eq_zero;
}

return Mask<T>(expand_top_bit(accept));
}

/**
* AND-combine two masks
*/
Expand Down
14 changes: 10 additions & 4 deletions src/lib/utils/ghash/ghash_cpu/ghash_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,16 @@ BOTAN_FORCE_INLINE SIMD_4x32 BOTAN_FUNC_ISA(BOTAN_CLMUL_ISA) clmul(const SIMD_4x
i2 = mask_lo.andc(i2);
}

return SIMD_4x32((__vector unsigned int)__builtin_crypto_vpmsumd(
(__vector unsigned long)i1.raw(),
(__vector unsigned long)i2.raw())
);
auto i1v = reinterpret_cast<__vector unsigned long long>(i1.raw());
auto i2v = reinterpret_cast<__vector unsigned long long>(i2.raw());

#if defined(__clang__)
auto rv = __builtin_altivec_crypto_vpmsumd(i1v, i2v);
#else
auto rv = __builtin_crypto_vpmsumd(i1v, i2v);
#endif

return SIMD_4x32(reinterpret_cast<__vector unsigned int>(rv));
#endif
}

Expand Down
100 changes: 0 additions & 100 deletions src/scripts/ci/travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,6 @@ compiler: gcc

jobs:
include:
- name: Coverage (GCC)
env:
- TARGET="coverage"
- CCACHE_MAXSIZE=2G
- PKCS11_LIB=/usr/lib/softhsm/libsofthsm2.so

- name: Fuzzers (GCC)
arch: arm64
env:
- TARGET="fuzzers"

- name: Valgrind (GCC)
env:
- TARGET="valgrind"
- CCACHE_MAXSIZE=2G

- name: Linux s390x (GCC)
arch: s390x
env:
- TARGET="shared"

- name: Linux ppc64le (GCC)
arch: ppc64le
env:
Expand All @@ -36,91 +15,12 @@ jobs:
env:
- TARGET="shared"

- name: Linux arm32 cross (GCC)
arch: arm64
env:
- TARGET="cross-arm32"

- name: Linux x86_64 (Clang)
compiler: clang
env:
- TARGET="shared"

- name: Linux ppc32 cross (GCC)
dist: xenial
env:
- TARGET="cross-ppc32"

- name: macOS x86_64 (XCode Clang)
os: osx
compiler: clang
env:
- TARGET="shared"

- name: iOS arm64 (XCode Clang)
os: osx
compiler: clang
env:
- TARGET="cross-arm64"

- name: Android arm32 cross (NDK Clang)
compiler: clang
env:
- TARGET="cross-android-arm32"
- ANDROID_NDK=android-ndk-r21d

- name: Android arm64 cross (NDK Clang)
compiler: clang
env:
- TARGET="cross-android-arm64"
- ANDROID_NDK=android-ndk-r21d

- name: MinGW x86-64 cross (GCC)
env:
- TARGET="cross-win64"

- name: Linux i386 cross (GCC)
env:
- TARGET="cross-i386"

- name: Linux GCC 4.8
dist: bionic
env:
- TARGET="gcc4.8"
- EXTRA_FLAGS="--disable-werror"

- name: Linux Clang 8
compiler: clang
env:
- TARGET="clang8"
- CXX="/usr/bin/clang++-8"

- name: Minimized
arch: arm64
env:
- TARGET="mini-shared"

- name: Baremetal (GCC)
arch: arm64
env:
- TARGET="baremetal"

- name: BSI policy
arch: arm64
env:
- TARGET="bsi"

- name: NIST policy
arch: arm64
env:
- TARGET="nist"

- name: Pylint
arch: arm64
dist: bionic
env:
- TARGET="lint"

install:
- ./src/scripts/ci/setup_travis.sh

Expand Down
6 changes: 4 additions & 2 deletions src/scripts/ci_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin,
else:
run_test_command = test_prefix + test_cmd

return flags, run_test_command, make_prefix
return flags, run_test_command, make_prefix, install_prefix

def run_cmd(cmd, root_dir):
"""
Expand Down Expand Up @@ -501,6 +501,7 @@ def main(args=None):
'src/python/botan2.py',
'src/scripts/ci_build.py',
'src/scripts/install.py',
'src/scripts/ci_check_install.py',
'src/scripts/dist.py',
'src/scripts/cleanup.py',
'src/scripts/check.py',
Expand All @@ -522,7 +523,7 @@ def main(args=None):
cmds.append(['python3', '-m', 'pylint'] + pylint_flags + [py3_flags] + full_paths)

else:
config_flags, run_test_command, make_prefix = determine_flags(
config_flags, run_test_command, make_prefix, install_prefix = determine_flags(
target, options.os, options.cpu, options.cc,
options.cc_bin, options.compiler_cache, root_dir,
options.pkcs11_lib, options.use_gdb, options.disable_werror,
Expand Down Expand Up @@ -606,6 +607,7 @@ def main(args=None):

if target in ['shared', 'static', 'bsi', 'nist']:
cmds.append(make_cmd + ['install'])
cmds.append([py_interp, os.path.join(root_dir, 'src/scripts/ci_check_install.py'), install_prefix])

if target in ['sonar']:

Expand Down
56 changes: 56 additions & 0 deletions src/scripts/ci_check_install.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python
# coding=utf8

"""
Botan CI check installation script
This script is used to validate the results of `make install`
(C) 2020 Jack Lloyd, René Meusel, Hannes Rantzsch
Botan is released under the Simplified BSD License (see license.txt)
"""

import os
import sys

def has_extension(filename, extensions):
for ext in [ext for ext in extensions]:
if filename.endswith(".%s" % ext):
return True
return False

def is_lib_file(filename):
return has_extension(filename, ["so", "a", "dll", "dylib", "lib"])

def is_header_file(filename):
return has_extension(filename, ["h", "hpp", "h++", "hxx", "hh"])

def main():
if len(sys.argv) < 2:
print("Usage: %s <install_prefix>" % sys.argv[0])
return 1
install_prefix = sys.argv[1]

if not os.path.isdir(install_prefix):
print('Error: install_prefix "%s" is not a directory' % install_prefix)
return 1

found_libs = False
found_headers = False

for (_, _, filenames) in os.walk(install_prefix):
for filename in filenames:
if is_header_file(filename):
found_headers = True
elif is_lib_file(filename):
found_libs = True
if found_libs and found_headers:
return 0

print("Error: installation incomplete. Found headers: %s. Found libs: %s. install_prefix was %s"
% (found_headers, found_libs, install_prefix))
return 1


if __name__ == '__main__':
sys.exit(main())