Skip to content

Commit

Permalink
Add uxxBitrev() functions
Browse files Browse the repository at this point in the history
  • Loading branch information
agievich committed Nov 18, 2024
1 parent eba3d81 commit 2eea7e5
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 9 deletions.
11 changes: 10 additions & 1 deletion include/bee2/core/u16.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief 16-bit words
\project bee2 [cryptographic library]
\created 2015.10.28
\version 2023.02.02
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -73,6 +73,15 @@ void u16Rev2(
size_t count /*!< [in] число элементов */
);

/*! \brief Реверс битов
Выполняется реверс битов u16-слова w.
\return Слово с переставленными битами.
*/
u16 u16Bitrev(
register u16 w /*!< [in] слово */
);

/*! \brief Вес
Определяется число ненулевых битов в u16-слове w.
Expand Down
11 changes: 10 additions & 1 deletion include/bee2/core/u32.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief 32-bit words
\project bee2 [cryptographic library]
\created 2015.10.28
\version 2023.02.02
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -73,6 +73,15 @@ void u32Rev2(
u32 buf[], /*!< [in,out] массив слов */
size_t count /*!< [in] число элементов */
);

/*! \brief Реверс битов
Выполняется реверс битов u32-слова w.
\return Слово с переставленными битами.
*/
u32 u32Bitrev(
register u32 w /*!< [in] слово */
);

/*! \brief Вес
Expand Down
11 changes: 10 additions & 1 deletion include/bee2/core/u64.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief 64-bit words
\project bee2 [cryptographic library]
\created 2015.10.28
\version 2023.02.02
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -85,6 +85,15 @@ void u64Rev2(
size_t count /*!< [in] число элементов */
);

/*! \brief Реверс битов
Выполняется реверс битов u64-слова w.
\return Слово с переставленными битами.
*/
u64 u64Bitrev(
register u64 w /*!< [in] слово */
);

/*! \brief Вес
Определяется число ненулевых битов в u64-слове w.
Expand Down
5 changes: 4 additions & 1 deletion include/bee2/core/word.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief Machine words
\project bee2 [cryptographic library]
\created 2014.07.18
\version 2019.06.27
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -50,6 +50,7 @@ extern "C" {
#define wordRotHi u16RotHi
#define wordRotLo u16RotLo
#define wordRev u16Rev
#define wordBitrev u16Bitrev
#define wordWeight u16Weight
#define wordParity u16Parity
#define wordCTZ u16CTZ
Expand All @@ -69,6 +70,7 @@ extern "C" {
#define wordRotHi u32RotHi
#define wordRotLo u32RotLo
#define wordRev u32Rev
#define wordBitrev u32Bitrev
#define wordWeight u32Weight
#define wordParity u32Parity
#define wordCTZ u32CTZ
Expand All @@ -88,6 +90,7 @@ extern "C" {
#define wordRotHi u64RotHi
#define wordRotLo u64RotLo
#define wordRev u64Rev
#define wordBitrev u64Bitrev
#define wordWeight u64Weight
#define wordParity u64Parity
#define wordCTZ u64CTZ
Expand Down
9 changes: 9 additions & 0 deletions src/core/u16.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ void u16Rev2(u16 buf[], size_t count)
buf[count] = u16Rev(buf[count]);
}

u16 u16Bitrev(register u16 w)
{
w = ((w >> 1) & 0x5555) | ((w & 0x5555) << 1);
w = ((w >> 2) & 0x3333) | ((w & 0x3333) << 2);
w = ((w >> 4) & 0x0F0F) | ((w & 0x0F0F) << 4);
w = (w >> 8) | (w << 8);
return w;
}

size_t u16Weight(register u16 w)
{
w -= ((w >> 1) & 0x5555);
Expand Down
23 changes: 22 additions & 1 deletion src/core/u32.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief 32-bit unsigned words
\project bee2 [cryptographic library]
\created 2015.10.28
\version 2022.07.05
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -47,6 +47,27 @@ void u32Rev2(u32 buf[], size_t count)
buf[count] = u32Rev(buf[count]);
}

/*
*******************************************************************************
Реверс битов
Реализован алгоритм, представленнный в [2] (Reverse an N-bit quantity
in parallel in 5 * lg(N) operations). Первоисточник:
* Freed, Edwin E. 1983. "Binary Magic Numbers," Dr. Dobb's Journal
Vol. 78 (April), pp. 24-37.
*******************************************************************************
*/

u32 u32Bitrev(register u32 w)
{
w = ((w >> 1) & 0x55555555) | ((w & 0x55555555) << 1);
w = ((w >> 2) & 0x33333333) | ((w & 0x33333333) << 2);
w = ((w >> 4) & 0x0F0F0F0F) | ((w & 0x0F0F0F0F) << 4);
w = ((w >> 8) & 0x00FF00FF) | ((w & 0x00FF00FF) << 8);
w = (w >> 16) | (w << 16);
return w;
}

/*
*******************************************************************************
Вес
Expand Down
13 changes: 12 additions & 1 deletion src/core/u64.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief 64-bit unsigned words
\project bee2 [cryptographic library]
\created 2015.10.28
\version 2019.07.08
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -36,6 +36,17 @@ void u64Rev2(u64 buf[], size_t count)
buf[count] = u64Rev(buf[count]);
}

u64 u64Bitrev(register u64 w)
{
w = ((w >> 1 ) & 0x5555555555555555) | ((w & 0x5555555555555555) << 1);
w = ((w >> 2 ) & 0x3333333333333333) | ((w & 0x3333333333333333) << 2);
w = ((w >> 4 ) & 0x0F0F0F0F0F0F0F0F) | ((w & 0x0F0F0F0F0F0F0F0F) << 4);
w = ((w >> 8 ) & 0x00FF00FF00FF00FF) | ((w & 0x00FF00FF00FF00FF) << 8);
w = ((w >> 16) & 0x0000FFFF0000FFFF) | ((w & 0x0000FFFF0000FFFF) << 16);
w = (w >> 32) | (w << 32);
return w;
}

size_t u64Weight(register u64 w)
{
w -= ((w >> 1) & 0x5555555555555555);
Expand Down
5 changes: 4 additions & 1 deletion test/core/u16_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief Tests for operations on 16-bit words
\project bee2/test
\created 2017.01.11
\version 2019.07.08
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -37,6 +37,9 @@ bool_t u16Test()
u16Rev2(a, 2), u16Rev2(a, 2);
if (a[0] != w || a[1] != u16Rev(w))
return FALSE;
// bit reverse
if (u16Bitrev(w) != 0x4080|| u16Bitrev(u16Bitrev(w)) != w)
return FALSE;
// weight / parity
if (u16Weight(0) != 0 || u16Parity(0) || !u16Parity(1) ||
u16Weight(0xA001) != 3 || !u16Parity(0xA001) ||
Expand Down
5 changes: 4 additions & 1 deletion test/core/u32_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief Tests for operations on 32-bit words
\project bee2/test
\created 2017.01.11
\version 2019.07.08
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -37,6 +37,9 @@ bool_t u32Test()
u32Rev2(a, 2), u32Rev2(a, 2);
if (a[0] != w || a[1] != u32Rev(w))
return FALSE;
// bit reverse
if (u32Bitrev(w) != 0x20C04080 || u32Bitrev(u32Bitrev(w)) != w)
return FALSE;
// weight / parity
if (u32Weight(0) != 0 || u32Parity(0) || !u32Parity(1) ||
u32Weight(0xA001) != 3 || !u32Parity(0xA001) ||
Expand Down
5 changes: 4 additions & 1 deletion test/core/u64_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
\brief Tests for operations on 64-bit words
\project bee2/test
\created 2017.01.11
\version 2019.07.08
\version 2024.11.18
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
Expand Down Expand Up @@ -38,6 +38,9 @@ bool_t u64Test()
u64Rev2(a, 2), u64Rev2(a, 2);
if (a[0] != w || a[1] != u64Rev(w))
return FALSE;
// bit reverse
if (u64Bitrev(w) != 0x10E060A020C04080 || u64Bitrev(u64Bitrev(w)) != w)
return FALSE;
// weight / parity
if (u64Weight(0) != 0 || u64Parity(0) || !u64Parity(1) ||
u64Weight(0xA001) != 3 || !u64Parity(0xA001) ||
Expand Down

0 comments on commit 2eea7e5

Please sign in to comment.