summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/pubkey/mce/gf2m_small_m.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/pubkey/mce/gf2m_small_m.cpp')
-rw-r--r--comm/third_party/botan/src/lib/pubkey/mce/gf2m_small_m.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/pubkey/mce/gf2m_small_m.cpp b/comm/third_party/botan/src/lib/pubkey/mce/gf2m_small_m.cpp
new file mode 100644
index 0000000000..341b45d034
--- /dev/null
+++ b/comm/third_party/botan/src/lib/pubkey/mce/gf2m_small_m.cpp
@@ -0,0 +1,126 @@
+/*
+* (C) Copyright Projet SECRET, INRIA, Rocquencourt
+* (C) Bhaskar Biswas and Nicolas Sendrier
+*
+* (C) 2014 cryptosource GmbH
+* (C) 2014 Falko Strenzke fstrenzke@cryptosource.de
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/gf2m_small_m.h>
+#include <botan/exceptn.h>
+#include <string>
+
+namespace Botan {
+
+#define MAX_EXT_DEG 16
+
+namespace {
+
+gf2m prim_poly[MAX_EXT_DEG + 1] = {
+ 01, /* extension degree 0 (!) never used */
+ 03, /* extension degree 1 (!) never used */
+ 07, /* extension degree 2 */
+ 013, /* extension degree 3 */
+ 023, /* extension degree 4 */
+ 045, /* extension degree 5 */
+ 0103, /* extension degree 6 */
+ 0203, /* extension degree 7 */
+ 0435, /* extension degree 8 */
+ 01041, /* extension degree 9 */
+ 02011, /* extension degree 10 */
+ 04005, /* extension degree 11 */
+ 010123, /* extension degree 12 */
+ 020033, /* extension degree 13 */
+ 042103, /* extension degree 14 */
+ 0100003, /* extension degree 15 */
+};
+
+std::vector<gf2m> gf_exp_table(size_t deg, gf2m prime_poly)
+ {
+ // construct the table gf_exp[i]=alpha^i
+
+ std::vector<gf2m> tab((static_cast<size_t>(1) << deg) + 1);
+
+ tab[0] = 1;
+ for(size_t i = 1; i < tab.size(); ++i)
+ {
+ const gf2m overflow = tab[i-1] >> (deg - 1);
+ tab[i] = (tab[i-1] << 1) ^ (overflow * prime_poly);
+ }
+
+ return tab;
+ }
+
+const std::vector<gf2m>& exp_table(size_t deg)
+ {
+ static std::vector<gf2m> tabs[MAX_EXT_DEG + 1];
+
+ if(deg < 2 || deg > MAX_EXT_DEG)
+ throw Invalid_Argument("GF2m_Field does not support degree " + std::to_string(deg));
+
+ if(tabs[deg].empty())
+ tabs[deg] = gf_exp_table(deg, prim_poly[deg]);
+
+ return tabs[deg];
+ }
+
+std::vector<gf2m> gf_log_table(size_t deg, const std::vector<gf2m>& exp)
+ {
+ std::vector<gf2m> tab(static_cast<size_t>(1) << deg);
+
+ tab[0] = static_cast<gf2m>((static_cast<gf2m>(1) << deg) - 1); // log of 0 is the order by convention
+ for(size_t i = 0; i < tab.size(); ++i)
+ {
+ tab[exp[i]] = static_cast<gf2m>(i);
+ }
+ return tab;
+ }
+
+const std::vector<gf2m>& log_table(size_t deg)
+ {
+ static std::vector<gf2m> tabs[MAX_EXT_DEG + 1];
+
+ if(deg < 2 || deg > MAX_EXT_DEG)
+ throw Invalid_Argument("GF2m_Field does not support degree " + std::to_string(deg));
+
+ if(tabs[deg].empty())
+ tabs[deg] = gf_log_table(deg, exp_table(deg));
+
+ return tabs[deg];
+ }
+
+}
+
+uint32_t encode_gf2m(gf2m to_enc, uint8_t* mem)
+ {
+ mem[0] = to_enc >> 8;
+ mem[1] = to_enc & 0xFF;
+ return sizeof(to_enc);
+ }
+
+gf2m decode_gf2m(const uint8_t* mem)
+ {
+ gf2m result;
+ result = mem[0] << 8;
+ result |= mem[1];
+ return result;
+ }
+
+GF2m_Field::GF2m_Field(size_t extdeg) : m_gf_extension_degree(extdeg),
+ m_gf_multiplicative_order((1 << extdeg) - 1),
+ m_gf_log_table(log_table(m_gf_extension_degree)),
+ m_gf_exp_table(exp_table(m_gf_extension_degree))
+ {
+ }
+
+gf2m GF2m_Field::gf_div(gf2m x, gf2m y) const
+ {
+ const int32_t sub_res = static_cast<int32_t>(gf_log(x) - static_cast<int32_t>(gf_log(y)));
+ const gf2m modq_res = _gf_modq_1(sub_res);
+ const int32_t div_res = static_cast<int32_t>(x) ? static_cast<int32_t>(gf_exp(modq_res)) : 0;
+ return static_cast<gf2m>(div_res);
+ }
+
+}