| // Copyright 2016 The Fuchsia Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef COBALT_SRC_ALGORITHMS_FORCULUS_FIELD_ELEMENT_H_ |
| #define COBALT_SRC_ALGORITHMS_FORCULUS_FIELD_ELEMENT_H_ |
| |
| #include <cstring> |
| #include <cwchar> |
| #include <iostream> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "src/lib/crypto_util/cipher.h" |
| #include "src/lib/crypto_util/types.h" |
| |
| namespace cobalt::forculus { |
| |
| using crypto::byte; |
| |
| // A FieldElement is an element of the Forculus Field, the field over which |
| // Forculs encryption takes place. |
| class FieldElement { |
| public: |
| // The number of bytes of data used to represent a FieldElement. The size |
| // of the Forculus Field is 2^{8 * kDataSize}. |
| static const size_t kDataSize = 256 / 8; |
| |
| // Constructs a FieldElement by moving kDataSize bytes out of |bytes|. |
| // If the length of |bytes| is greater than kDataSize than the extra bytes |
| // will be discarded from the end. If the length of |bytes| is less than |
| // kDataSize then zero bytes will be appendeed to the end. |
| explicit FieldElement(std::vector<byte>&& bytes); |
| |
| // Constructs a FieldElement by copying kDataSize bytes out of the string |
| // |data|. If the size of |data| is greater than kDataSize than the extra |
| // bytes will be discarded from the end. If the size of |data| is less than |
| // kDataSize then zero bytes will be appendeed to the end. |
| explicit FieldElement(const std::string& data); |
| |
| // Constructs the FieldElement zero or one depending on the value of |one|. |
| explicit FieldElement(bool one); |
| |
| // Move constructor. |
| FieldElement(FieldElement&& other) = default; |
| |
| // Copy constructor. |
| FieldElement(const FieldElement& other) = default; |
| |
| // Copy assignment operator |
| FieldElement& operator=(const FieldElement& other) = default; |
| |
| // Move assignment operator |
| FieldElement& operator=(FieldElement&& other) = default; |
| |
| bool operator==(const FieldElement& other) const { return bytes_ == other.bytes_; } |
| |
| bool operator!=(const FieldElement& other) const { return bytes_ != other.bytes_; } |
| |
| // FieldElements are ordered lexicographically by their byte representation. |
| // There is nothing mathematically natural about this ordering but having |
| // some ordering is necessary in order to use FieldElements as the keys |
| // of a map. |
| bool operator<(const FieldElement& other) const { return bytes_ < other.bytes_; } |
| |
| // Convenience function that copies the underlying bytes of this element |
| // into *target_string. |
| void CopyBytesToString(std::string* target_string) const { |
| target_string->assign(reinterpret_cast<const char*>(bytes_.data()), bytes_.size()); |
| } |
| |
| // Returns a pointer to a buffer of bytes of length |
| // crypto::SymmetricCipher::KEY_SIZE that may be used as the key to a |
| // symmetric cipher. The returned bytes are based on the underlying byte |
| // representation of the FieldElement. Each FieldElement yields a different |
| // key. |
| [[nodiscard]] const byte* KeyBytes() const; |
| |
| // Arithmetic operations below |
| |
| // Returns the sum of this element plus the |other| element. |
| FieldElement operator+(const FieldElement& other) const; |
| |
| // Sets this element to the sum of this element and the |other| element. |
| void operator+=(const FieldElement& other); |
| |
| // Returns the difference of this element minus the |other| element. |
| FieldElement operator-(const FieldElement& other) const; |
| |
| // Sets this element to the difference of this element minus the |other|. |
| void operator-=(const FieldElement& other); |
| |
| // Returns the product of this element times the |other| element. |
| FieldElement operator*(const FieldElement& other) const; |
| |
| // Sets this element to the product of this element and the |other| element. |
| void operator*=(const FieldElement& other); |
| |
| // Returns the quotient of this element divided by the |other| element. |
| // The behavior is undefined if |other| is the zero element. |
| FieldElement operator/(const FieldElement& other) const; |
| |
| // Sets this element to the quotent of this element divided by the |other|. |
| // The behavior is undefined if |other| is the zero element. |
| void operator/=(const FieldElement& other); |
| |
| private: |
| std::vector<byte> bytes_; |
| }; |
| |
| std::ostream& operator<<(std::ostream& os, const FieldElement& el); |
| |
| } // namespace cobalt::forculus |
| |
| #endif // COBALT_SRC_ALGORITHMS_FORCULUS_FIELD_ELEMENT_H_ |