summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/pubkey/ed25519/ed25519_fe.h
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/pubkey/ed25519/ed25519_fe.h')
-rw-r--r--comm/third_party/botan/src/lib/pubkey/ed25519/ed25519_fe.h227
1 files changed, 227 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/pubkey/ed25519/ed25519_fe.h b/comm/third_party/botan/src/lib/pubkey/ed25519/ed25519_fe.h
new file mode 100644
index 0000000000..bcdc36a5e2
--- /dev/null
+++ b/comm/third_party/botan/src/lib/pubkey/ed25519/ed25519_fe.h
@@ -0,0 +1,227 @@
+/*
+* Ed25519 field element
+* (C) 2017 Ribose Inc
+*
+* Based on the public domain code from SUPERCOP ref10 by
+* Peter Schwabe, Daniel J. Bernstein, Niels Duif, Tanja Lange, Bo-Yin Yang
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_ED25519_FE_H_
+#define BOTAN_ED25519_FE_H_
+
+#include <botan/mem_ops.h>
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+/**
+* An element of the field \\Z/(2^255-19)
+*/
+class FE_25519
+ {
+ public:
+ ~FE_25519() { secure_scrub_memory(m_fe, sizeof(m_fe)); }
+
+ /**
+ * Zero element
+ */
+ FE_25519(int init = 0)
+ {
+ if(init != 0 && init != 1)
+ throw Invalid_Argument("Invalid FE_25519 initial value");
+ clear_mem(m_fe, 10);
+ m_fe[0] = init;
+ }
+
+ FE_25519(std::initializer_list<int32_t> x)
+ {
+ if(x.size() != 10)
+ throw Invalid_Argument("Invalid FE_25519 initializer list");
+ copy_mem(m_fe, x.begin(), 10);
+ }
+
+ FE_25519(int64_t h0, int64_t h1, int64_t h2, int64_t h3, int64_t h4,
+ int64_t h5, int64_t h6, int64_t h7, int64_t h8, int64_t h9)
+ {
+ m_fe[0] = static_cast<int32_t>(h0);
+ m_fe[1] = static_cast<int32_t>(h1);
+ m_fe[2] = static_cast<int32_t>(h2);
+ m_fe[3] = static_cast<int32_t>(h3);
+ m_fe[4] = static_cast<int32_t>(h4);
+ m_fe[5] = static_cast<int32_t>(h5);
+ m_fe[6] = static_cast<int32_t>(h6);
+ m_fe[7] = static_cast<int32_t>(h7);
+ m_fe[8] = static_cast<int32_t>(h8);
+ m_fe[9] = static_cast<int32_t>(h9);
+ }
+
+ FE_25519(const FE_25519& other) = default;
+ FE_25519& operator=(const FE_25519& other) = default;
+
+ FE_25519(FE_25519&& other) = default;
+ FE_25519& operator=(FE_25519&& other) = default;
+
+ void from_bytes(const uint8_t b[32]);
+ void to_bytes(uint8_t b[32]) const;
+
+ bool is_zero() const
+ {
+ uint8_t s[32];
+ to_bytes(s);
+
+ uint8_t sum = 0;
+ for(size_t i = 0; i != 32; ++i)
+ { sum |= s[i]; }
+
+ // TODO avoid ternary here
+ return (sum == 0) ? 1 : 0;
+ }
+
+ /*
+ return 1 if f is in {1,3,5,...,q-2}
+ return 0 if f is in {0,2,4,...,q-1}
+ */
+ bool is_negative() const
+ {
+ // TODO could avoid most of the to_bytes computation here
+ uint8_t s[32];
+ to_bytes(s);
+ return s[0] & 1;
+ }
+
+ static FE_25519 add(const FE_25519& a, const FE_25519& b)
+ {
+ FE_25519 z;
+ for(size_t i = 0; i != 10; ++i)
+ { z[i] = a[i] + b[i]; }
+ return z;
+ }
+
+ static FE_25519 sub(const FE_25519& a, const FE_25519& b)
+ {
+ FE_25519 z;
+ for(size_t i = 0; i != 10; ++i)
+ { z[i] = a[i] - b[i]; }
+ return z;
+ }
+
+ static FE_25519 negate(const FE_25519& a)
+ {
+ FE_25519 z;
+ for(size_t i = 0; i != 10; ++i)
+ { z[i] = -a[i]; }
+ return z;
+ }
+
+ static FE_25519 mul(const FE_25519& a, const FE_25519& b);
+ static FE_25519 sqr_iter(const FE_25519& a, size_t iter);
+ static FE_25519 sqr(const FE_25519& a) { return sqr_iter(a, 1); }
+ static FE_25519 sqr2(const FE_25519& a);
+ static FE_25519 pow_22523(const FE_25519& a);
+ static FE_25519 invert(const FE_25519& a);
+
+ // TODO remove
+ int32_t operator[](size_t i) const { return m_fe[i]; }
+ int32_t& operator[](size_t i) { return m_fe[i]; }
+
+ private:
+
+ int32_t m_fe[10];
+ };
+
+typedef FE_25519 fe;
+
+/*
+fe means field element.
+Here the field is
+An element t, entries t[0]...t[9], represents the integer
+t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
+Bounds on each t[i] vary depending on context.
+*/
+
+inline void fe_frombytes(fe& x, const uint8_t* b)
+ {
+ x.from_bytes(b);
+ }
+
+inline void fe_tobytes(uint8_t* b, const fe& x)
+ {
+ x.to_bytes(b);
+ }
+
+inline void fe_copy(fe& a, const fe& b)
+ {
+ a = b;
+ }
+
+inline int fe_isnonzero(const fe& x)
+ {
+ return x.is_zero() ? 0 : 1;
+ }
+
+inline int fe_isnegative(const fe& x)
+ {
+ return x.is_negative();
+ }
+
+
+inline void fe_0(fe& x)
+ {
+ x = FE_25519();
+ }
+
+inline void fe_1(fe& x)
+ {
+ x = FE_25519(1);
+ }
+
+inline void fe_add(fe& x, const fe& a, const fe& b)
+ {
+ x = FE_25519::add(a, b);
+ }
+
+inline void fe_sub(fe& x, const fe& a, const fe& b)
+ {
+ x = FE_25519::sub(a, b);
+ }
+
+inline void fe_neg(fe& x, const fe& z)
+ {
+ x = FE_25519::negate(z);
+ }
+
+inline void fe_mul(fe& x, const fe& a, const fe& b)
+ {
+ x = FE_25519::mul(a, b);
+ }
+
+inline void fe_sq(fe& x, const fe& z)
+ {
+ x = FE_25519::sqr(z);
+ }
+
+inline void fe_sq_iter(fe& x, const fe& z, size_t iter)
+ {
+ x = FE_25519::sqr_iter(z, iter);
+ }
+
+inline void fe_sq2(fe& x, const fe& z)
+ {
+ x = FE_25519::sqr2(z);
+ }
+
+inline void fe_invert(fe& x, const fe& z)
+ {
+ x = FE_25519::invert(z);
+ }
+
+inline void fe_pow22523(fe& x, const fe& y)
+ {
+ x = FE_25519::pow_22523(y);
+ }
+
+}
+
+#endif