blob: a7d1eddefb0529bb9b171a6893279d923d466579 [file] [log] [blame]
// 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_ALGORITHMS_FORCULUS_FIELD_ELEMENT_H_
#define COBALT_ALGORITHMS_FORCULUS_FIELD_ELEMENT_H_
#include <cstring>
#include <cwchar>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "util/crypto_util/types.h"
namespace cobalt {
namespace 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) : bytes_(std::move(other.bytes_)) {}
// Copy constructor.
FieldElement(const FieldElement& other) : bytes_(other.bytes_) {}
// Copy assignment operator
void operator=(const FieldElement& other) {
bytes_ = other.bytes_;
}
// Move assignment operator
void operator=(FieldElement&& other) {
bytes_ = std::move(other.bytes_);
}
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) {
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.
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 forculus
} // namespace cobalt
#endif // COBALT_ALGORITHMS_FORCULUS_FIELD_ELEMENT_H_