libdpf/include/dpf/aes_sbox_bp.hpp

162 lines
4.1 KiB
C++
Raw Normal View History

/// @file dpf/aes_sbox_bp.hpp
/// @brief Boyar–Peralta AES S-box (Yale CMT SLP, 32 ANDs) over XOR bit shares.
/// @details Circuit: http://www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt
/// (Boyar and Peralta, ePrint 2011/332). Matches the AES S-box used
/// by `aes_ref` / hardware AES. `#` is XNOR.
#ifndef LIBDPF_INCLUDE_DPF_AES_SBOX_BP_HPP__
#define LIBDPF_INCLUDE_DPF_AES_SBOX_BP_HPP__
#include <cstddef>
#include <cstdint>
namespace aes_bp
{
inline constexpr std::size_t wire_count = 121;
inline constexpr std::size_t op_count = 113;
inline constexpr std::size_t and_count = 32;
/// @brief Multiplicative depth of the SLP (XOR/XNOR are free).
inline constexpr std::size_t and_layer_count = 6;
inline constexpr std::uint8_t out_wire[8] = {114,117,119,107,116,120,115,111};
/// @brief AND-op indices in `ops` grouped by multiplicative depth.
/// @details XOR/XNOR between layers stay local. Every AND in a layer has
/// both inputs ready, so one exchange covers the whole layer
/// (and every S-box byte sharing that schedule).
inline constexpr std::uint8_t and_layer_size[and_layer_count] = {9, 1, 2, 7, 5, 8};
inline constexpr std::uint8_t and_layer_ops[and_layer_count][9] = {
{23, 24, 26, 28, 29, 31, 33, 34, 36},
{47},
{49, 53},
{57, 69, 72, 73, 78, 81, 82},
{60, 67, 68, 76, 77},
{70, 71, 74, 75, 79, 80, 83, 84},
};
static_assert(
and_layer_size[0] + and_layer_size[1] + and_layer_size[2]
+ and_layer_size[3] + and_layer_size[4] + and_layer_size[5]
== and_count,
"Boyar–Peralta AND layer sizes must cover every AND");
// kind: 0=XOR, 1=AND, 2=XNOR. Each row is {kind, dst, a, b}.
inline constexpr std::uint8_t ops[op_count][4] = {
{0, 8, 3, 5},
{0, 9, 0, 6},
{0, 10, 0, 3},
{0, 11, 0, 5},
{0, 12, 1, 2},
{0, 13, 12, 7},
{0, 14, 13, 3},
{0, 15, 9, 8},
{0, 16, 13, 0},
{0, 17, 13, 6},
{0, 18, 17, 11},
{0, 19, 4, 15},
{0, 20, 19, 5},
{0, 21, 19, 1},
{0, 22, 20, 7},
{0, 23, 20, 12},
{0, 24, 21, 10},
{0, 25, 7, 24},
{0, 26, 23, 24},
{0, 27, 23, 11},
{0, 28, 12, 24},
{0, 29, 9, 28},
{0, 30, 0, 28},
{1, 31, 15, 20},
{1, 32, 18, 22},
{0, 33, 32, 31},
{1, 34, 14, 7},
{0, 35, 34, 31},
{1, 36, 9, 28},
{1, 37, 17, 13},
{0, 38, 37, 36},
{1, 39, 16, 25},
{0, 40, 39, 36},
{1, 41, 10, 24},
{1, 42, 8, 26},
{0, 43, 42, 41},
{1, 44, 11, 23},
{0, 45, 44, 41},
{0, 46, 33, 21},
{0, 47, 35, 45},
{0, 48, 38, 43},
{0, 49, 40, 45},
{0, 50, 46, 43},
{0, 51, 47, 27},
{0, 52, 48, 29},
{0, 53, 49, 30},
{0, 54, 50, 51},
{1, 55, 50, 52},
{0, 56, 53, 55},
{1, 57, 54, 56},
{0, 58, 57, 51},
{0, 59, 52, 53},
{0, 60, 51, 55},
{1, 61, 60, 59},
{0, 62, 61, 53},
{0, 63, 52, 62},
{0, 64, 56, 62},
{1, 65, 53, 64},
{0, 66, 65, 63},
{0, 67, 56, 65},
{1, 68, 58, 67},
{0, 69, 54, 68},
{0, 70, 69, 66},
{0, 71, 58, 62},
{0, 72, 58, 69},
{0, 73, 62, 66},
{0, 74, 71, 70},
{1, 75, 73, 20},
{1, 76, 66, 22},
{1, 77, 62, 7},
{1, 78, 72, 28},
{1, 79, 69, 13},
{1, 80, 58, 25},
{1, 81, 71, 24},
{1, 82, 74, 26},
{1, 83, 70, 23},
{1, 84, 73, 15},
{1, 85, 66, 18},
{1, 86, 62, 14},
{1, 87, 72, 9},
{1, 88, 69, 17},
{1, 89, 58, 16},
{1, 90, 71, 10},
{1, 91, 74, 8},
{1, 92, 70, 11},
{0, 93, 90, 91},
{0, 94, 85, 93},
{0, 95, 84, 94},
{0, 96, 75, 77},
{0, 97, 76, 75},
{0, 98, 78, 79},
{0, 99, 87, 96},
{0, 100, 82, 98},
{0, 101, 83, 99},
{0, 102, 100, 101},
{0, 103, 98, 97},
{0, 104, 78, 80},
{0, 105, 88, 93},
{0, 106, 96, 104},
{0, 107, 95, 103},
{0, 108, 81, 100},
{0, 109, 89, 102},
{0, 110, 105, 106},
{2, 111, 87, 110},
{0, 112, 90, 108},
{0, 113, 94, 86},
{0, 114, 95, 108},
{2, 115, 102, 110},
{0, 116, 106, 107},
{2, 117, 107, 108},
{0, 118, 109, 112},
{2, 119, 118, 92},
{0, 120, 113, 109},
};
} // namespace aes_bp
#endif // LIBDPF_INCLUDE_DPF_AES_SBOX_BP_HPP__