// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: Messages.proto

#ifndef PROTOBUF_Messages_2eproto__INCLUDED
#define PROTOBUF_Messages_2eproto__INCLUDED

#include <string>

#include <google/protobuf/stubs/common.h>

#if GOOGLE_PROTOBUF_VERSION < 3000000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please update
#error your headers.
#endif
#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)

namespace Messages {

// Internal implementation detail -- do not call these.
void protobuf_AddDesc_Messages_2eproto();
void protobuf_AssignDesc_Messages_2eproto();
void protobuf_ShutdownFile_Messages_2eproto();

class AttestationMessage;
class InitialMessage;
class MessageMSG1;
class MessageMSG2;
class MessageMSG3;
class MessageMsg0;

// ===================================================================

class InitialMessage : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.InitialMessage) */ {
 public:
  InitialMessage();
  virtual ~InitialMessage();

  InitialMessage(const InitialMessage& from);

  inline InitialMessage& operator=(const InitialMessage& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const InitialMessage& default_instance();

  void Swap(InitialMessage* other);

  // implements Message ----------------------------------------------

  inline InitialMessage* New() const { return New(NULL); }

  InitialMessage* New(::google::protobuf::Arena* arena) const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const InitialMessage& from);
  void MergeFrom(const InitialMessage& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
    return InternalSerializeWithCachedSizesToArray(false, output);
  }
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(InitialMessage* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // required uint32 type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::google::protobuf::uint32 type() const;
  void set_type(::google::protobuf::uint32 value);

  // optional uint32 size = 2;
  bool has_size() const;
  void clear_size();
  static const int kSizeFieldNumber = 2;
  ::google::protobuf::uint32 size() const;
  void set_size(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:Messages.InitialMessage)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

  void InitAsDefaultInstance();
  static InitialMessage* default_instance_;
};
// -------------------------------------------------------------------

class MessageMsg0 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMsg0) */ {
 public:
  MessageMsg0();
  virtual ~MessageMsg0();

  MessageMsg0(const MessageMsg0& from);

  inline MessageMsg0& operator=(const MessageMsg0& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MessageMsg0& default_instance();

  void Swap(MessageMsg0* other);

  // implements Message ----------------------------------------------

  inline MessageMsg0* New() const { return New(NULL); }

  MessageMsg0* New(::google::protobuf::Arena* arena) const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMsg0& from);
  void MergeFrom(const MessageMsg0& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
    return InternalSerializeWithCachedSizesToArray(false, output);
  }
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(MessageMsg0* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // required uint32 type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::google::protobuf::uint32 type() const;
  void set_type(::google::protobuf::uint32 value);

  // required uint32 epid = 2;
  bool has_epid() const;
  void clear_epid();
  static const int kEpidFieldNumber = 2;
  ::google::protobuf::uint32 epid() const;
  void set_epid(::google::protobuf::uint32 value);

  // optional uint32 status = 3;
  bool has_status() const;
  void clear_status();
  static const int kStatusFieldNumber = 3;
  ::google::protobuf::uint32 status() const;
  void set_status(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:Messages.MessageMsg0)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_epid();
  inline void clear_has_epid();
  inline void set_has_status();
  inline void clear_has_status();

  // helper for ByteSize()
  int RequiredFieldsByteSizeFallback() const;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 epid_;
  ::google::protobuf::uint32 status_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

  void InitAsDefaultInstance();
  static MessageMsg0* default_instance_;
};
// -------------------------------------------------------------------

class MessageMSG1 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMSG1) */ {
 public:
  MessageMSG1();
  virtual ~MessageMSG1();

  MessageMSG1(const MessageMSG1& from);

  inline MessageMSG1& operator=(const MessageMSG1& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MessageMSG1& default_instance();

  void Swap(MessageMSG1* other);

  // implements Message ----------------------------------------------

  inline MessageMSG1* New() const { return New(NULL); }

  MessageMSG1* New(::google::protobuf::Arena* arena) const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMSG1& from);
  void MergeFrom(const MessageMSG1& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
    return InternalSerializeWithCachedSizesToArray(false, output);
  }
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(MessageMSG1* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // required uint32 type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::google::protobuf::uint32 type() const;
  void set_type(::google::protobuf::uint32 value);

  // repeated uint32 GaX = 2 [packed = true];
  int gax_size() const;
  void clear_gax();
  static const int kGaXFieldNumber = 2;
  ::google::protobuf::uint32 gax(int index) const;
  void set_gax(int index, ::google::protobuf::uint32 value);
  void add_gax(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gax() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gax();

  // repeated uint32 GaY = 3 [packed = true];
  int gay_size() const;
  void clear_gay();
  static const int kGaYFieldNumber = 3;
  ::google::protobuf::uint32 gay(int index) const;
  void set_gay(int index, ::google::protobuf::uint32 value);
  void add_gay(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gay() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gay();

  // repeated uint32 GID = 4 [packed = true];
  int gid_size() const;
  void clear_gid();
  static const int kGIDFieldNumber = 4;
  ::google::protobuf::uint32 gid(int index) const;
  void set_gid(int index, ::google::protobuf::uint32 value);
  void add_gid(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gid() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gid();

  // @@protoc_insertion_point(class_scope:Messages.MessageMSG1)
 private:
  inline void set_has_type();
  inline void clear_has_type();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gax_;
  mutable int _gax_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gay_;
  mutable int _gay_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gid_;
  mutable int _gid_cached_byte_size_;
  ::google::protobuf::uint32 type_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

  void InitAsDefaultInstance();
  static MessageMSG1* default_instance_;
};
// -------------------------------------------------------------------

class MessageMSG2 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMSG2) */ {
 public:
  MessageMSG2();
  virtual ~MessageMSG2();

  MessageMSG2(const MessageMSG2& from);

  inline MessageMSG2& operator=(const MessageMSG2& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MessageMSG2& default_instance();

  void Swap(MessageMSG2* other);

  // implements Message ----------------------------------------------

  inline MessageMSG2* New() const { return New(NULL); }

  MessageMSG2* New(::google::protobuf::Arena* arena) const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMSG2& from);
  void MergeFrom(const MessageMSG2& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
    return InternalSerializeWithCachedSizesToArray(false, output);
  }
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(MessageMSG2* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // required uint32 type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::google::protobuf::uint32 type() const;
  void set_type(::google::protobuf::uint32 value);

  // optional uint32 size = 2;
  bool has_size() const;
  void clear_size();
  static const int kSizeFieldNumber = 2;
  ::google::protobuf::uint32 size() const;
  void set_size(::google::protobuf::uint32 value);

  // repeated uint32 public_key_gx = 3 [packed = true];
  int public_key_gx_size() const;
  void clear_public_key_gx();
  static const int kPublicKeyGxFieldNumber = 3;
  ::google::protobuf::uint32 public_key_gx(int index) const;
  void set_public_key_gx(int index, ::google::protobuf::uint32 value);
  void add_public_key_gx(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      public_key_gx() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_public_key_gx();

  // repeated uint32 public_key_gy = 4 [packed = true];
  int public_key_gy_size() const;
  void clear_public_key_gy();
  static const int kPublicKeyGyFieldNumber = 4;
  ::google::protobuf::uint32 public_key_gy(int index) const;
  void set_public_key_gy(int index, ::google::protobuf::uint32 value);
  void add_public_key_gy(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      public_key_gy() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_public_key_gy();

  // optional uint32 quote_type = 5;
  bool has_quote_type() const;
  void clear_quote_type();
  static const int kQuoteTypeFieldNumber = 5;
  ::google::protobuf::uint32 quote_type() const;
  void set_quote_type(::google::protobuf::uint32 value);

  // repeated uint32 spid = 6 [packed = true];
  int spid_size() const;
  void clear_spid();
  static const int kSpidFieldNumber = 6;
  ::google::protobuf::uint32 spid(int index) const;
  void set_spid(int index, ::google::protobuf::uint32 value);
  void add_spid(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      spid() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_spid();

  // optional uint32 cmac_kdf_id = 7;
  bool has_cmac_kdf_id() const;
  void clear_cmac_kdf_id();
  static const int kCmacKdfIdFieldNumber = 7;
  ::google::protobuf::uint32 cmac_kdf_id() const;
  void set_cmac_kdf_id(::google::protobuf::uint32 value);

  // repeated uint32 signature_x = 8 [packed = true];
  int signature_x_size() const;
  void clear_signature_x();
  static const int kSignatureXFieldNumber = 8;
  ::google::protobuf::uint32 signature_x(int index) const;
  void set_signature_x(int index, ::google::protobuf::uint32 value);
  void add_signature_x(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      signature_x() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_signature_x();

  // repeated uint32 signature_y = 9 [packed = true];
  int signature_y_size() const;
  void clear_signature_y();
  static const int kSignatureYFieldNumber = 9;
  ::google::protobuf::uint32 signature_y(int index) const;
  void set_signature_y(int index, ::google::protobuf::uint32 value);
  void add_signature_y(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      signature_y() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_signature_y();

  // repeated uint32 smac = 10 [packed = true];
  int smac_size() const;
  void clear_smac();
  static const int kSmacFieldNumber = 10;
  ::google::protobuf::uint32 smac(int index) const;
  void set_smac(int index, ::google::protobuf::uint32 value);
  void add_smac(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      smac() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_smac();

  // optional uint32 size_sigrl = 11;
  bool has_size_sigrl() const;
  void clear_size_sigrl();
  static const int kSizeSigrlFieldNumber = 11;
  ::google::protobuf::uint32 size_sigrl() const;
  void set_size_sigrl(::google::protobuf::uint32 value);

  // repeated uint32 sigrl = 12 [packed = true];
  int sigrl_size() const;
  void clear_sigrl();
  static const int kSigrlFieldNumber = 12;
  ::google::protobuf::uint32 sigrl(int index) const;
  void set_sigrl(int index, ::google::protobuf::uint32 value);
  void add_sigrl(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      sigrl() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_sigrl();

  // @@protoc_insertion_point(class_scope:Messages.MessageMSG2)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_quote_type();
  inline void clear_has_quote_type();
  inline void set_has_cmac_kdf_id();
  inline void clear_has_cmac_kdf_id();
  inline void set_has_size_sigrl();
  inline void clear_has_size_sigrl();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > public_key_gx_;
  mutable int _public_key_gx_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > public_key_gy_;
  mutable int _public_key_gy_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > spid_;
  mutable int _spid_cached_byte_size_;
  ::google::protobuf::uint32 quote_type_;
  ::google::protobuf::uint32 cmac_kdf_id_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > signature_x_;
  mutable int _signature_x_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > signature_y_;
  mutable int _signature_y_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > smac_;
  mutable int _smac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > sigrl_;
  mutable int _sigrl_cached_byte_size_;
  ::google::protobuf::uint32 size_sigrl_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

  void InitAsDefaultInstance();
  static MessageMSG2* default_instance_;
};
// -------------------------------------------------------------------

class MessageMSG3 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMSG3) */ {
 public:
  MessageMSG3();
  virtual ~MessageMSG3();

  MessageMSG3(const MessageMSG3& from);

  inline MessageMSG3& operator=(const MessageMSG3& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MessageMSG3& default_instance();

  void Swap(MessageMSG3* other);

  // implements Message ----------------------------------------------

  inline MessageMSG3* New() const { return New(NULL); }

  MessageMSG3* New(::google::protobuf::Arena* arena) const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageMSG3& from);
  void MergeFrom(const MessageMSG3& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
    return InternalSerializeWithCachedSizesToArray(false, output);
  }
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(MessageMSG3* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // required uint32 type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::google::protobuf::uint32 type() const;
  void set_type(::google::protobuf::uint32 value);

  // optional uint32 size = 2;
  bool has_size() const;
  void clear_size();
  static const int kSizeFieldNumber = 2;
  ::google::protobuf::uint32 size() const;
  void set_size(::google::protobuf::uint32 value);

  // repeated uint32 sgx_mac = 3 [packed = true];
  int sgx_mac_size() const;
  void clear_sgx_mac();
  static const int kSgxMacFieldNumber = 3;
  ::google::protobuf::uint32 sgx_mac(int index) const;
  void set_sgx_mac(int index, ::google::protobuf::uint32 value);
  void add_sgx_mac(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      sgx_mac() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_sgx_mac();

  // repeated uint32 gax_msg3 = 4 [packed = true];
  int gax_msg3_size() const;
  void clear_gax_msg3();
  static const int kGaxMsg3FieldNumber = 4;
  ::google::protobuf::uint32 gax_msg3(int index) const;
  void set_gax_msg3(int index, ::google::protobuf::uint32 value);
  void add_gax_msg3(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gax_msg3() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gax_msg3();

  // repeated uint32 gay_msg3 = 5 [packed = true];
  int gay_msg3_size() const;
  void clear_gay_msg3();
  static const int kGayMsg3FieldNumber = 5;
  ::google::protobuf::uint32 gay_msg3(int index) const;
  void set_gay_msg3(int index, ::google::protobuf::uint32 value);
  void add_gay_msg3(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      gay_msg3() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_gay_msg3();

  // repeated uint32 sec_property = 6 [packed = true];
  int sec_property_size() const;
  void clear_sec_property();
  static const int kSecPropertyFieldNumber = 6;
  ::google::protobuf::uint32 sec_property(int index) const;
  void set_sec_property(int index, ::google::protobuf::uint32 value);
  void add_sec_property(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      sec_property() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_sec_property();

  // repeated uint32 quote = 7 [packed = true];
  int quote_size() const;
  void clear_quote();
  static const int kQuoteFieldNumber = 7;
  ::google::protobuf::uint32 quote(int index) const;
  void set_quote(int index, ::google::protobuf::uint32 value);
  void add_quote(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      quote() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_quote();

  // @@protoc_insertion_point(class_scope:Messages.MessageMSG3)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > sgx_mac_;
  mutable int _sgx_mac_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gax_msg3_;
  mutable int _gax_msg3_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gay_msg3_;
  mutable int _gay_msg3_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > sec_property_;
  mutable int _sec_property_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > quote_;
  mutable int _quote_cached_byte_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

  void InitAsDefaultInstance();
  static MessageMSG3* default_instance_;
};
// -------------------------------------------------------------------

class AttestationMessage : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.AttestationMessage) */ {
 public:
  AttestationMessage();
  virtual ~AttestationMessage();

  AttestationMessage(const AttestationMessage& from);

  inline AttestationMessage& operator=(const AttestationMessage& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const AttestationMessage& default_instance();

  void Swap(AttestationMessage* other);

  // implements Message ----------------------------------------------

  inline AttestationMessage* New() const { return New(NULL); }

  AttestationMessage* New(::google::protobuf::Arena* arena) const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const AttestationMessage& from);
  void MergeFrom(const AttestationMessage& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
    return InternalSerializeWithCachedSizesToArray(false, output);
  }
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(AttestationMessage* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // required uint32 type = 1;
  bool has_type() const;
  void clear_type();
  static const int kTypeFieldNumber = 1;
  ::google::protobuf::uint32 type() const;
  void set_type(::google::protobuf::uint32 value);

  // required uint32 size = 2;
  bool has_size() const;
  void clear_size();
  static const int kSizeFieldNumber = 2;
  ::google::protobuf::uint32 size() const;
  void set_size(::google::protobuf::uint32 value);

  // optional uint32 epid_group_status = 3;
  bool has_epid_group_status() const;
  void clear_epid_group_status();
  static const int kEpidGroupStatusFieldNumber = 3;
  ::google::protobuf::uint32 epid_group_status() const;
  void set_epid_group_status(::google::protobuf::uint32 value);

  // optional uint32 tcb_evaluation_status = 4;
  bool has_tcb_evaluation_status() const;
  void clear_tcb_evaluation_status();
  static const int kTcbEvaluationStatusFieldNumber = 4;
  ::google::protobuf::uint32 tcb_evaluation_status() const;
  void set_tcb_evaluation_status(::google::protobuf::uint32 value);

  // optional uint32 pse_evaluation_status = 5;
  bool has_pse_evaluation_status() const;
  void clear_pse_evaluation_status();
  static const int kPseEvaluationStatusFieldNumber = 5;
  ::google::protobuf::uint32 pse_evaluation_status() const;
  void set_pse_evaluation_status(::google::protobuf::uint32 value);

  // repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
  int latest_equivalent_tcb_psvn_size() const;
  void clear_latest_equivalent_tcb_psvn();
  static const int kLatestEquivalentTcbPsvnFieldNumber = 6;
  ::google::protobuf::uint32 latest_equivalent_tcb_psvn(int index) const;
  void set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value);
  void add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      latest_equivalent_tcb_psvn() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_latest_equivalent_tcb_psvn();

  // repeated uint32 latest_pse_isvsvn = 7 [packed = true];
  int latest_pse_isvsvn_size() const;
  void clear_latest_pse_isvsvn();
  static const int kLatestPseIsvsvnFieldNumber = 7;
  ::google::protobuf::uint32 latest_pse_isvsvn(int index) const;
  void set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value);
  void add_latest_pse_isvsvn(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      latest_pse_isvsvn() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_latest_pse_isvsvn();

  // repeated uint32 latest_psda_svn = 8 [packed = true];
  int latest_psda_svn_size() const;
  void clear_latest_psda_svn();
  static const int kLatestPsdaSvnFieldNumber = 8;
  ::google::protobuf::uint32 latest_psda_svn(int index) const;
  void set_latest_psda_svn(int index, ::google::protobuf::uint32 value);
  void add_latest_psda_svn(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      latest_psda_svn() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_latest_psda_svn();

  // repeated uint32 performance_rekey_gid = 9 [packed = true];
  int performance_rekey_gid_size() const;
  void clear_performance_rekey_gid();
  static const int kPerformanceRekeyGidFieldNumber = 9;
  ::google::protobuf::uint32 performance_rekey_gid(int index) const;
  void set_performance_rekey_gid(int index, ::google::protobuf::uint32 value);
  void add_performance_rekey_gid(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      performance_rekey_gid() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_performance_rekey_gid();

  // repeated uint32 ec_sign256_x = 10 [packed = true];
  int ec_sign256_x_size() const;
  void clear_ec_sign256_x();
  static const int kEcSign256XFieldNumber = 10;
  ::google::protobuf::uint32 ec_sign256_x(int index) const;
  void set_ec_sign256_x(int index, ::google::protobuf::uint32 value);
  void add_ec_sign256_x(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      ec_sign256_x() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_ec_sign256_x();

  // repeated uint32 ec_sign256_y = 11 [packed = true];
  int ec_sign256_y_size() const;
  void clear_ec_sign256_y();
  static const int kEcSign256YFieldNumber = 11;
  ::google::protobuf::uint32 ec_sign256_y(int index) const;
  void set_ec_sign256_y(int index, ::google::protobuf::uint32 value);
  void add_ec_sign256_y(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      ec_sign256_y() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_ec_sign256_y();

  // repeated uint32 mac_smk = 12 [packed = true];
  int mac_smk_size() const;
  void clear_mac_smk();
  static const int kMacSmkFieldNumber = 12;
  ::google::protobuf::uint32 mac_smk(int index) const;
  void set_mac_smk(int index, ::google::protobuf::uint32 value);
  void add_mac_smk(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      mac_smk() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_mac_smk();

  // optional uint32 result_size = 13;
  bool has_result_size() const;
  void clear_result_size();
  static const int kResultSizeFieldNumber = 13;
  ::google::protobuf::uint32 result_size() const;
  void set_result_size(::google::protobuf::uint32 value);

  // repeated uint32 reserved = 14 [packed = true];
  int reserved_size() const;
  void clear_reserved();
  static const int kReservedFieldNumber = 14;
  ::google::protobuf::uint32 reserved(int index) const;
  void set_reserved(int index, ::google::protobuf::uint32 value);
  void add_reserved(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      reserved() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_reserved();

  // repeated uint32 payload_tag = 15 [packed = true];
  int payload_tag_size() const;
  void clear_payload_tag();
  static const int kPayloadTagFieldNumber = 15;
  ::google::protobuf::uint32 payload_tag(int index) const;
  void set_payload_tag(int index, ::google::protobuf::uint32 value);
  void add_payload_tag(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      payload_tag() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_payload_tag();

  // repeated uint32 payload = 16 [packed = true];
  int payload_size() const;
  void clear_payload();
  static const int kPayloadFieldNumber = 16;
  ::google::protobuf::uint32 payload(int index) const;
  void set_payload(int index, ::google::protobuf::uint32 value);
  void add_payload(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      payload() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_payload();

  // @@protoc_insertion_point(class_scope:Messages.AttestationMessage)
 private:
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_size();
  inline void clear_has_size();
  inline void set_has_epid_group_status();
  inline void clear_has_epid_group_status();
  inline void set_has_tcb_evaluation_status();
  inline void clear_has_tcb_evaluation_status();
  inline void set_has_pse_evaluation_status();
  inline void clear_has_pse_evaluation_status();
  inline void set_has_result_size();
  inline void clear_has_result_size();

  // helper for ByteSize()
  int RequiredFieldsByteSizeFallback() const;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint32 type_;
  ::google::protobuf::uint32 size_;
  ::google::protobuf::uint32 epid_group_status_;
  ::google::protobuf::uint32 tcb_evaluation_status_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > latest_equivalent_tcb_psvn_;
  mutable int _latest_equivalent_tcb_psvn_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > latest_pse_isvsvn_;
  mutable int _latest_pse_isvsvn_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > latest_psda_svn_;
  mutable int _latest_psda_svn_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > performance_rekey_gid_;
  mutable int _performance_rekey_gid_cached_byte_size_;
  ::google::protobuf::uint32 pse_evaluation_status_;
  ::google::protobuf::uint32 result_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > ec_sign256_x_;
  mutable int _ec_sign256_x_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > ec_sign256_y_;
  mutable int _ec_sign256_y_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > mac_smk_;
  mutable int _mac_smk_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > reserved_;
  mutable int _reserved_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > payload_tag_;
  mutable int _payload_tag_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > payload_;
  mutable int _payload_cached_byte_size_;
  friend void  protobuf_AddDesc_Messages_2eproto();
  friend void protobuf_AssignDesc_Messages_2eproto();
  friend void protobuf_ShutdownFile_Messages_2eproto();

  void InitAsDefaultInstance();
  static AttestationMessage* default_instance_;
};
// ===================================================================


// ===================================================================

#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// InitialMessage

// required uint32 type = 1;
inline bool InitialMessage::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void InitialMessage::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void InitialMessage::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void InitialMessage::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 InitialMessage::type() const {
  // @@protoc_insertion_point(field_get:Messages.InitialMessage.type)
  return type_;
}
inline void InitialMessage::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.InitialMessage.type)
}

// optional uint32 size = 2;
inline bool InitialMessage::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void InitialMessage::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void InitialMessage::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void InitialMessage::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 InitialMessage::size() const {
  // @@protoc_insertion_point(field_get:Messages.InitialMessage.size)
  return size_;
}
inline void InitialMessage::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.InitialMessage.size)
}

// -------------------------------------------------------------------

// MessageMsg0

// required uint32 type = 1;
inline bool MessageMsg0::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMsg0::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMsg0::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMsg0::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMsg0::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMsg0.type)
  return type_;
}
inline void MessageMsg0::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMsg0.type)
}

// required uint32 epid = 2;
inline bool MessageMsg0::has_epid() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMsg0::set_has_epid() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMsg0::clear_has_epid() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMsg0::clear_epid() {
  epid_ = 0u;
  clear_has_epid();
}
inline ::google::protobuf::uint32 MessageMsg0::epid() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMsg0.epid)
  return epid_;
}
inline void MessageMsg0::set_epid(::google::protobuf::uint32 value) {
  set_has_epid();
  epid_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMsg0.epid)
}

// optional uint32 status = 3;
inline bool MessageMsg0::has_status() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageMsg0::set_has_status() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageMsg0::clear_has_status() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageMsg0::clear_status() {
  status_ = 0u;
  clear_has_status();
}
inline ::google::protobuf::uint32 MessageMsg0::status() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMsg0.status)
  return status_;
}
inline void MessageMsg0::set_status(::google::protobuf::uint32 value) {
  set_has_status();
  status_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMsg0.status)
}

// -------------------------------------------------------------------

// MessageMSG1

// required uint32 type = 1;
inline bool MessageMSG1::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMSG1::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMSG1::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMSG1::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMSG1::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.type)
  return type_;
}
inline void MessageMSG1::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.type)
}

// repeated uint32 GaX = 2 [packed = true];
inline int MessageMSG1::gax_size() const {
  return gax_.size();
}
inline void MessageMSG1::clear_gax() {
  gax_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG1::gax(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GaX)
  return gax_.Get(index);
}
inline void MessageMSG1::set_gax(int index, ::google::protobuf::uint32 value) {
  gax_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GaX)
}
inline void MessageMSG1::add_gax(::google::protobuf::uint32 value) {
  gax_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GaX)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG1::gax() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GaX)
  return gax_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG1::mutable_gax() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GaX)
  return &gax_;
}

// repeated uint32 GaY = 3 [packed = true];
inline int MessageMSG1::gay_size() const {
  return gay_.size();
}
inline void MessageMSG1::clear_gay() {
  gay_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG1::gay(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GaY)
  return gay_.Get(index);
}
inline void MessageMSG1::set_gay(int index, ::google::protobuf::uint32 value) {
  gay_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GaY)
}
inline void MessageMSG1::add_gay(::google::protobuf::uint32 value) {
  gay_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GaY)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG1::gay() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GaY)
  return gay_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG1::mutable_gay() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GaY)
  return &gay_;
}

// repeated uint32 GID = 4 [packed = true];
inline int MessageMSG1::gid_size() const {
  return gid_.size();
}
inline void MessageMSG1::clear_gid() {
  gid_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG1::gid(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GID)
  return gid_.Get(index);
}
inline void MessageMSG1::set_gid(int index, ::google::protobuf::uint32 value) {
  gid_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GID)
}
inline void MessageMSG1::add_gid(::google::protobuf::uint32 value) {
  gid_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GID)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG1::gid() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GID)
  return gid_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG1::mutable_gid() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GID)
  return &gid_;
}

// -------------------------------------------------------------------

// MessageMSG2

// required uint32 type = 1;
inline bool MessageMSG2::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMSG2::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMSG2::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMSG2::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMSG2::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.type)
  return type_;
}
inline void MessageMSG2::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.type)
}

// optional uint32 size = 2;
inline bool MessageMSG2::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMSG2::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMSG2::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMSG2::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessageMSG2::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.size)
  return size_;
}
inline void MessageMSG2::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.size)
}

// repeated uint32 public_key_gx = 3 [packed = true];
inline int MessageMSG2::public_key_gx_size() const {
  return public_key_gx_.size();
}
inline void MessageMSG2::clear_public_key_gx() {
  public_key_gx_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::public_key_gx(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.public_key_gx)
  return public_key_gx_.Get(index);
}
inline void MessageMSG2::set_public_key_gx(int index, ::google::protobuf::uint32 value) {
  public_key_gx_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.public_key_gx)
}
inline void MessageMSG2::add_public_key_gx(::google::protobuf::uint32 value) {
  public_key_gx_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.public_key_gx)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::public_key_gx() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.public_key_gx)
  return public_key_gx_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_public_key_gx() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.public_key_gx)
  return &public_key_gx_;
}

// repeated uint32 public_key_gy = 4 [packed = true];
inline int MessageMSG2::public_key_gy_size() const {
  return public_key_gy_.size();
}
inline void MessageMSG2::clear_public_key_gy() {
  public_key_gy_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::public_key_gy(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.public_key_gy)
  return public_key_gy_.Get(index);
}
inline void MessageMSG2::set_public_key_gy(int index, ::google::protobuf::uint32 value) {
  public_key_gy_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.public_key_gy)
}
inline void MessageMSG2::add_public_key_gy(::google::protobuf::uint32 value) {
  public_key_gy_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.public_key_gy)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::public_key_gy() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.public_key_gy)
  return public_key_gy_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_public_key_gy() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.public_key_gy)
  return &public_key_gy_;
}

// optional uint32 quote_type = 5;
inline bool MessageMSG2::has_quote_type() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void MessageMSG2::set_has_quote_type() {
  _has_bits_[0] |= 0x00000010u;
}
inline void MessageMSG2::clear_has_quote_type() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void MessageMSG2::clear_quote_type() {
  quote_type_ = 0u;
  clear_has_quote_type();
}
inline ::google::protobuf::uint32 MessageMSG2::quote_type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.quote_type)
  return quote_type_;
}
inline void MessageMSG2::set_quote_type(::google::protobuf::uint32 value) {
  set_has_quote_type();
  quote_type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.quote_type)
}

// repeated uint32 spid = 6 [packed = true];
inline int MessageMSG2::spid_size() const {
  return spid_.size();
}
inline void MessageMSG2::clear_spid() {
  spid_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::spid(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.spid)
  return spid_.Get(index);
}
inline void MessageMSG2::set_spid(int index, ::google::protobuf::uint32 value) {
  spid_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.spid)
}
inline void MessageMSG2::add_spid(::google::protobuf::uint32 value) {
  spid_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.spid)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::spid() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.spid)
  return spid_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_spid() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.spid)
  return &spid_;
}

// optional uint32 cmac_kdf_id = 7;
inline bool MessageMSG2::has_cmac_kdf_id() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void MessageMSG2::set_has_cmac_kdf_id() {
  _has_bits_[0] |= 0x00000040u;
}
inline void MessageMSG2::clear_has_cmac_kdf_id() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void MessageMSG2::clear_cmac_kdf_id() {
  cmac_kdf_id_ = 0u;
  clear_has_cmac_kdf_id();
}
inline ::google::protobuf::uint32 MessageMSG2::cmac_kdf_id() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.cmac_kdf_id)
  return cmac_kdf_id_;
}
inline void MessageMSG2::set_cmac_kdf_id(::google::protobuf::uint32 value) {
  set_has_cmac_kdf_id();
  cmac_kdf_id_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.cmac_kdf_id)
}

// repeated uint32 signature_x = 8 [packed = true];
inline int MessageMSG2::signature_x_size() const {
  return signature_x_.size();
}
inline void MessageMSG2::clear_signature_x() {
  signature_x_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::signature_x(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.signature_x)
  return signature_x_.Get(index);
}
inline void MessageMSG2::set_signature_x(int index, ::google::protobuf::uint32 value) {
  signature_x_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.signature_x)
}
inline void MessageMSG2::add_signature_x(::google::protobuf::uint32 value) {
  signature_x_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.signature_x)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::signature_x() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.signature_x)
  return signature_x_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_signature_x() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.signature_x)
  return &signature_x_;
}

// repeated uint32 signature_y = 9 [packed = true];
inline int MessageMSG2::signature_y_size() const {
  return signature_y_.size();
}
inline void MessageMSG2::clear_signature_y() {
  signature_y_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::signature_y(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.signature_y)
  return signature_y_.Get(index);
}
inline void MessageMSG2::set_signature_y(int index, ::google::protobuf::uint32 value) {
  signature_y_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.signature_y)
}
inline void MessageMSG2::add_signature_y(::google::protobuf::uint32 value) {
  signature_y_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.signature_y)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::signature_y() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.signature_y)
  return signature_y_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_signature_y() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.signature_y)
  return &signature_y_;
}

// repeated uint32 smac = 10 [packed = true];
inline int MessageMSG2::smac_size() const {
  return smac_.size();
}
inline void MessageMSG2::clear_smac() {
  smac_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::smac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.smac)
  return smac_.Get(index);
}
inline void MessageMSG2::set_smac(int index, ::google::protobuf::uint32 value) {
  smac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.smac)
}
inline void MessageMSG2::add_smac(::google::protobuf::uint32 value) {
  smac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.smac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::smac() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.smac)
  return smac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_smac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.smac)
  return &smac_;
}

// optional uint32 size_sigrl = 11;
inline bool MessageMSG2::has_size_sigrl() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void MessageMSG2::set_has_size_sigrl() {
  _has_bits_[0] |= 0x00000400u;
}
inline void MessageMSG2::clear_has_size_sigrl() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void MessageMSG2::clear_size_sigrl() {
  size_sigrl_ = 0u;
  clear_has_size_sigrl();
}
inline ::google::protobuf::uint32 MessageMSG2::size_sigrl() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.size_sigrl)
  return size_sigrl_;
}
inline void MessageMSG2::set_size_sigrl(::google::protobuf::uint32 value) {
  set_has_size_sigrl();
  size_sigrl_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.size_sigrl)
}

// repeated uint32 sigrl = 12 [packed = true];
inline int MessageMSG2::sigrl_size() const {
  return sigrl_.size();
}
inline void MessageMSG2::clear_sigrl() {
  sigrl_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG2::sigrl(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG2.sigrl)
  return sigrl_.Get(index);
}
inline void MessageMSG2::set_sigrl(int index, ::google::protobuf::uint32 value) {
  sigrl_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG2.sigrl)
}
inline void MessageMSG2::add_sigrl(::google::protobuf::uint32 value) {
  sigrl_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG2.sigrl)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG2::sigrl() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG2.sigrl)
  return sigrl_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG2::mutable_sigrl() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.sigrl)
  return &sigrl_;
}

// -------------------------------------------------------------------

// MessageMSG3

// required uint32 type = 1;
inline bool MessageMSG3::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageMSG3::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageMSG3::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageMSG3::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 MessageMSG3::type() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.type)
  return type_;
}
inline void MessageMSG3::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.type)
}

// optional uint32 size = 2;
inline bool MessageMSG3::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageMSG3::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageMSG3::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageMSG3::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 MessageMSG3::size() const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.size)
  return size_;
}
inline void MessageMSG3::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.size)
}

// repeated uint32 sgx_mac = 3 [packed = true];
inline int MessageMSG3::sgx_mac_size() const {
  return sgx_mac_.size();
}
inline void MessageMSG3::clear_sgx_mac() {
  sgx_mac_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::sgx_mac(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.sgx_mac)
  return sgx_mac_.Get(index);
}
inline void MessageMSG3::set_sgx_mac(int index, ::google::protobuf::uint32 value) {
  sgx_mac_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.sgx_mac)
}
inline void MessageMSG3::add_sgx_mac(::google::protobuf::uint32 value) {
  sgx_mac_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.sgx_mac)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::sgx_mac() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.sgx_mac)
  return sgx_mac_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_sgx_mac() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.sgx_mac)
  return &sgx_mac_;
}

// repeated uint32 gax_msg3 = 4 [packed = true];
inline int MessageMSG3::gax_msg3_size() const {
  return gax_msg3_.size();
}
inline void MessageMSG3::clear_gax_msg3() {
  gax_msg3_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::gax_msg3(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.gax_msg3)
  return gax_msg3_.Get(index);
}
inline void MessageMSG3::set_gax_msg3(int index, ::google::protobuf::uint32 value) {
  gax_msg3_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.gax_msg3)
}
inline void MessageMSG3::add_gax_msg3(::google::protobuf::uint32 value) {
  gax_msg3_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.gax_msg3)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::gax_msg3() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.gax_msg3)
  return gax_msg3_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_gax_msg3() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.gax_msg3)
  return &gax_msg3_;
}

// repeated uint32 gay_msg3 = 5 [packed = true];
inline int MessageMSG3::gay_msg3_size() const {
  return gay_msg3_.size();
}
inline void MessageMSG3::clear_gay_msg3() {
  gay_msg3_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::gay_msg3(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.gay_msg3)
  return gay_msg3_.Get(index);
}
inline void MessageMSG3::set_gay_msg3(int index, ::google::protobuf::uint32 value) {
  gay_msg3_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.gay_msg3)
}
inline void MessageMSG3::add_gay_msg3(::google::protobuf::uint32 value) {
  gay_msg3_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.gay_msg3)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::gay_msg3() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.gay_msg3)
  return gay_msg3_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_gay_msg3() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.gay_msg3)
  return &gay_msg3_;
}

// repeated uint32 sec_property = 6 [packed = true];
inline int MessageMSG3::sec_property_size() const {
  return sec_property_.size();
}
inline void MessageMSG3::clear_sec_property() {
  sec_property_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::sec_property(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.sec_property)
  return sec_property_.Get(index);
}
inline void MessageMSG3::set_sec_property(int index, ::google::protobuf::uint32 value) {
  sec_property_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.sec_property)
}
inline void MessageMSG3::add_sec_property(::google::protobuf::uint32 value) {
  sec_property_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.sec_property)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::sec_property() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.sec_property)
  return sec_property_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_sec_property() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.sec_property)
  return &sec_property_;
}

// repeated uint32 quote = 7 [packed = true];
inline int MessageMSG3::quote_size() const {
  return quote_.size();
}
inline void MessageMSG3::clear_quote() {
  quote_.Clear();
}
inline ::google::protobuf::uint32 MessageMSG3::quote(int index) const {
  // @@protoc_insertion_point(field_get:Messages.MessageMSG3.quote)
  return quote_.Get(index);
}
inline void MessageMSG3::set_quote(int index, ::google::protobuf::uint32 value) {
  quote_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.MessageMSG3.quote)
}
inline void MessageMSG3::add_quote(::google::protobuf::uint32 value) {
  quote_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.MessageMSG3.quote)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
MessageMSG3::quote() const {
  // @@protoc_insertion_point(field_list:Messages.MessageMSG3.quote)
  return quote_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
MessageMSG3::mutable_quote() {
  // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.quote)
  return &quote_;
}

// -------------------------------------------------------------------

// AttestationMessage

// required uint32 type = 1;
inline bool AttestationMessage::has_type() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void AttestationMessage::set_has_type() {
  _has_bits_[0] |= 0x00000001u;
}
inline void AttestationMessage::clear_has_type() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void AttestationMessage::clear_type() {
  type_ = 0u;
  clear_has_type();
}
inline ::google::protobuf::uint32 AttestationMessage::type() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.type)
  return type_;
}
inline void AttestationMessage::set_type(::google::protobuf::uint32 value) {
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.type)
}

// required uint32 size = 2;
inline bool AttestationMessage::has_size() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void AttestationMessage::set_has_size() {
  _has_bits_[0] |= 0x00000002u;
}
inline void AttestationMessage::clear_has_size() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void AttestationMessage::clear_size() {
  size_ = 0u;
  clear_has_size();
}
inline ::google::protobuf::uint32 AttestationMessage::size() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.size)
  return size_;
}
inline void AttestationMessage::set_size(::google::protobuf::uint32 value) {
  set_has_size();
  size_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.size)
}

// optional uint32 epid_group_status = 3;
inline bool AttestationMessage::has_epid_group_status() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void AttestationMessage::set_has_epid_group_status() {
  _has_bits_[0] |= 0x00000004u;
}
inline void AttestationMessage::clear_has_epid_group_status() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void AttestationMessage::clear_epid_group_status() {
  epid_group_status_ = 0u;
  clear_has_epid_group_status();
}
inline ::google::protobuf::uint32 AttestationMessage::epid_group_status() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.epid_group_status)
  return epid_group_status_;
}
inline void AttestationMessage::set_epid_group_status(::google::protobuf::uint32 value) {
  set_has_epid_group_status();
  epid_group_status_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.epid_group_status)
}

// optional uint32 tcb_evaluation_status = 4;
inline bool AttestationMessage::has_tcb_evaluation_status() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void AttestationMessage::set_has_tcb_evaluation_status() {
  _has_bits_[0] |= 0x00000008u;
}
inline void AttestationMessage::clear_has_tcb_evaluation_status() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void AttestationMessage::clear_tcb_evaluation_status() {
  tcb_evaluation_status_ = 0u;
  clear_has_tcb_evaluation_status();
}
inline ::google::protobuf::uint32 AttestationMessage::tcb_evaluation_status() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.tcb_evaluation_status)
  return tcb_evaluation_status_;
}
inline void AttestationMessage::set_tcb_evaluation_status(::google::protobuf::uint32 value) {
  set_has_tcb_evaluation_status();
  tcb_evaluation_status_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.tcb_evaluation_status)
}

// optional uint32 pse_evaluation_status = 5;
inline bool AttestationMessage::has_pse_evaluation_status() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void AttestationMessage::set_has_pse_evaluation_status() {
  _has_bits_[0] |= 0x00000010u;
}
inline void AttestationMessage::clear_has_pse_evaluation_status() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void AttestationMessage::clear_pse_evaluation_status() {
  pse_evaluation_status_ = 0u;
  clear_has_pse_evaluation_status();
}
inline ::google::protobuf::uint32 AttestationMessage::pse_evaluation_status() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.pse_evaluation_status)
  return pse_evaluation_status_;
}
inline void AttestationMessage::set_pse_evaluation_status(::google::protobuf::uint32 value) {
  set_has_pse_evaluation_status();
  pse_evaluation_status_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.pse_evaluation_status)
}

// repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
inline int AttestationMessage::latest_equivalent_tcb_psvn_size() const {
  return latest_equivalent_tcb_psvn_.size();
}
inline void AttestationMessage::clear_latest_equivalent_tcb_psvn() {
  latest_equivalent_tcb_psvn_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::latest_equivalent_tcb_psvn(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
  return latest_equivalent_tcb_psvn_.Get(index);
}
inline void AttestationMessage::set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value) {
  latest_equivalent_tcb_psvn_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
}
inline void AttestationMessage::add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value) {
  latest_equivalent_tcb_psvn_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::latest_equivalent_tcb_psvn() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
  return latest_equivalent_tcb_psvn_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_latest_equivalent_tcb_psvn() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
  return &latest_equivalent_tcb_psvn_;
}

// repeated uint32 latest_pse_isvsvn = 7 [packed = true];
inline int AttestationMessage::latest_pse_isvsvn_size() const {
  return latest_pse_isvsvn_.size();
}
inline void AttestationMessage::clear_latest_pse_isvsvn() {
  latest_pse_isvsvn_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::latest_pse_isvsvn(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_pse_isvsvn)
  return latest_pse_isvsvn_.Get(index);
}
inline void AttestationMessage::set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value) {
  latest_pse_isvsvn_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_pse_isvsvn)
}
inline void AttestationMessage::add_latest_pse_isvsvn(::google::protobuf::uint32 value) {
  latest_pse_isvsvn_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_pse_isvsvn)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::latest_pse_isvsvn() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_pse_isvsvn)
  return latest_pse_isvsvn_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_latest_pse_isvsvn() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_pse_isvsvn)
  return &latest_pse_isvsvn_;
}

// repeated uint32 latest_psda_svn = 8 [packed = true];
inline int AttestationMessage::latest_psda_svn_size() const {
  return latest_psda_svn_.size();
}
inline void AttestationMessage::clear_latest_psda_svn() {
  latest_psda_svn_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::latest_psda_svn(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_psda_svn)
  return latest_psda_svn_.Get(index);
}
inline void AttestationMessage::set_latest_psda_svn(int index, ::google::protobuf::uint32 value) {
  latest_psda_svn_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_psda_svn)
}
inline void AttestationMessage::add_latest_psda_svn(::google::protobuf::uint32 value) {
  latest_psda_svn_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_psda_svn)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::latest_psda_svn() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_psda_svn)
  return latest_psda_svn_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_latest_psda_svn() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_psda_svn)
  return &latest_psda_svn_;
}

// repeated uint32 performance_rekey_gid = 9 [packed = true];
inline int AttestationMessage::performance_rekey_gid_size() const {
  return performance_rekey_gid_.size();
}
inline void AttestationMessage::clear_performance_rekey_gid() {
  performance_rekey_gid_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::performance_rekey_gid(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.performance_rekey_gid)
  return performance_rekey_gid_.Get(index);
}
inline void AttestationMessage::set_performance_rekey_gid(int index, ::google::protobuf::uint32 value) {
  performance_rekey_gid_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.performance_rekey_gid)
}
inline void AttestationMessage::add_performance_rekey_gid(::google::protobuf::uint32 value) {
  performance_rekey_gid_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.performance_rekey_gid)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::performance_rekey_gid() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.performance_rekey_gid)
  return performance_rekey_gid_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_performance_rekey_gid() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.performance_rekey_gid)
  return &performance_rekey_gid_;
}

// repeated uint32 ec_sign256_x = 10 [packed = true];
inline int AttestationMessage::ec_sign256_x_size() const {
  return ec_sign256_x_.size();
}
inline void AttestationMessage::clear_ec_sign256_x() {
  ec_sign256_x_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::ec_sign256_x(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.ec_sign256_x)
  return ec_sign256_x_.Get(index);
}
inline void AttestationMessage::set_ec_sign256_x(int index, ::google::protobuf::uint32 value) {
  ec_sign256_x_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.ec_sign256_x)
}
inline void AttestationMessage::add_ec_sign256_x(::google::protobuf::uint32 value) {
  ec_sign256_x_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.ec_sign256_x)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::ec_sign256_x() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.ec_sign256_x)
  return ec_sign256_x_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_ec_sign256_x() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.ec_sign256_x)
  return &ec_sign256_x_;
}

// repeated uint32 ec_sign256_y = 11 [packed = true];
inline int AttestationMessage::ec_sign256_y_size() const {
  return ec_sign256_y_.size();
}
inline void AttestationMessage::clear_ec_sign256_y() {
  ec_sign256_y_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::ec_sign256_y(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.ec_sign256_y)
  return ec_sign256_y_.Get(index);
}
inline void AttestationMessage::set_ec_sign256_y(int index, ::google::protobuf::uint32 value) {
  ec_sign256_y_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.ec_sign256_y)
}
inline void AttestationMessage::add_ec_sign256_y(::google::protobuf::uint32 value) {
  ec_sign256_y_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.ec_sign256_y)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::ec_sign256_y() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.ec_sign256_y)
  return ec_sign256_y_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_ec_sign256_y() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.ec_sign256_y)
  return &ec_sign256_y_;
}

// repeated uint32 mac_smk = 12 [packed = true];
inline int AttestationMessage::mac_smk_size() const {
  return mac_smk_.size();
}
inline void AttestationMessage::clear_mac_smk() {
  mac_smk_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::mac_smk(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.mac_smk)
  return mac_smk_.Get(index);
}
inline void AttestationMessage::set_mac_smk(int index, ::google::protobuf::uint32 value) {
  mac_smk_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.mac_smk)
}
inline void AttestationMessage::add_mac_smk(::google::protobuf::uint32 value) {
  mac_smk_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.mac_smk)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::mac_smk() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.mac_smk)
  return mac_smk_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_mac_smk() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.mac_smk)
  return &mac_smk_;
}

// optional uint32 result_size = 13;
inline bool AttestationMessage::has_result_size() const {
  return (_has_bits_[0] & 0x00001000u) != 0;
}
inline void AttestationMessage::set_has_result_size() {
  _has_bits_[0] |= 0x00001000u;
}
inline void AttestationMessage::clear_has_result_size() {
  _has_bits_[0] &= ~0x00001000u;
}
inline void AttestationMessage::clear_result_size() {
  result_size_ = 0u;
  clear_has_result_size();
}
inline ::google::protobuf::uint32 AttestationMessage::result_size() const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.result_size)
  return result_size_;
}
inline void AttestationMessage::set_result_size(::google::protobuf::uint32 value) {
  set_has_result_size();
  result_size_ = value;
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.result_size)
}

// repeated uint32 reserved = 14 [packed = true];
inline int AttestationMessage::reserved_size() const {
  return reserved_.size();
}
inline void AttestationMessage::clear_reserved() {
  reserved_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::reserved(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.reserved)
  return reserved_.Get(index);
}
inline void AttestationMessage::set_reserved(int index, ::google::protobuf::uint32 value) {
  reserved_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.reserved)
}
inline void AttestationMessage::add_reserved(::google::protobuf::uint32 value) {
  reserved_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.reserved)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::reserved() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.reserved)
  return reserved_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_reserved() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.reserved)
  return &reserved_;
}

// repeated uint32 payload_tag = 15 [packed = true];
inline int AttestationMessage::payload_tag_size() const {
  return payload_tag_.size();
}
inline void AttestationMessage::clear_payload_tag() {
  payload_tag_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::payload_tag(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.payload_tag)
  return payload_tag_.Get(index);
}
inline void AttestationMessage::set_payload_tag(int index, ::google::protobuf::uint32 value) {
  payload_tag_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.payload_tag)
}
inline void AttestationMessage::add_payload_tag(::google::protobuf::uint32 value) {
  payload_tag_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.payload_tag)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::payload_tag() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.payload_tag)
  return payload_tag_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_payload_tag() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.payload_tag)
  return &payload_tag_;
}

// repeated uint32 payload = 16 [packed = true];
inline int AttestationMessage::payload_size() const {
  return payload_.size();
}
inline void AttestationMessage::clear_payload() {
  payload_.Clear();
}
inline ::google::protobuf::uint32 AttestationMessage::payload(int index) const {
  // @@protoc_insertion_point(field_get:Messages.AttestationMessage.payload)
  return payload_.Get(index);
}
inline void AttestationMessage::set_payload(int index, ::google::protobuf::uint32 value) {
  payload_.Set(index, value);
  // @@protoc_insertion_point(field_set:Messages.AttestationMessage.payload)
}
inline void AttestationMessage::add_payload(::google::protobuf::uint32 value) {
  payload_.Add(value);
  // @@protoc_insertion_point(field_add:Messages.AttestationMessage.payload)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
AttestationMessage::payload() const {
  // @@protoc_insertion_point(field_list:Messages.AttestationMessage.payload)
  return payload_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
AttestationMessage::mutable_payload() {
  // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.payload)
  return &payload_;
}

#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

}  // namespace Messages

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_Messages_2eproto__INCLUDED
