// Copyright 2020 Google Inc.
//
// 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.
//
////////////////////////////////////////////////////////////////////////////////

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: third_party/tink/proto/aes_cmac.proto

package aes_cmac_go_proto

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type AesCmacParams struct {
	TagSize              uint32   `protobuf:"varint,1,opt,name=tag_size,json=tagSize,proto3" json:"tag_size,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *AesCmacParams) Reset()         { *m = AesCmacParams{} }
func (m *AesCmacParams) String() string { return proto.CompactTextString(m) }
func (*AesCmacParams) ProtoMessage()    {}
func (*AesCmacParams) Descriptor() ([]byte, []int) {
	return fileDescriptor_0723dd6d150a325c, []int{0}
}

func (m *AesCmacParams) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_AesCmacParams.Unmarshal(m, b)
}
func (m *AesCmacParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_AesCmacParams.Marshal(b, m, deterministic)
}
func (m *AesCmacParams) XXX_Merge(src proto.Message) {
	xxx_messageInfo_AesCmacParams.Merge(m, src)
}
func (m *AesCmacParams) XXX_Size() int {
	return xxx_messageInfo_AesCmacParams.Size(m)
}
func (m *AesCmacParams) XXX_DiscardUnknown() {
	xxx_messageInfo_AesCmacParams.DiscardUnknown(m)
}

var xxx_messageInfo_AesCmacParams proto.InternalMessageInfo

func (m *AesCmacParams) GetTagSize() uint32 {
	if m != nil {
		return m.TagSize
	}
	return 0
}

// key_type: type.googleapis.com/google.crypto.tink.AesCmacKey
type AesCmacKey struct {
	Version              uint32         `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
	KeyValue             []byte         `protobuf:"bytes,2,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"`
	Params               *AesCmacParams `protobuf:"bytes,3,opt,name=params,proto3" json:"params,omitempty"`
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
	XXX_unrecognized     []byte         `json:"-"`
	XXX_sizecache        int32          `json:"-"`
}

func (m *AesCmacKey) Reset()         { *m = AesCmacKey{} }
func (m *AesCmacKey) String() string { return proto.CompactTextString(m) }
func (*AesCmacKey) ProtoMessage()    {}
func (*AesCmacKey) Descriptor() ([]byte, []int) {
	return fileDescriptor_0723dd6d150a325c, []int{1}
}

func (m *AesCmacKey) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_AesCmacKey.Unmarshal(m, b)
}
func (m *AesCmacKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_AesCmacKey.Marshal(b, m, deterministic)
}
func (m *AesCmacKey) XXX_Merge(src proto.Message) {
	xxx_messageInfo_AesCmacKey.Merge(m, src)
}
func (m *AesCmacKey) XXX_Size() int {
	return xxx_messageInfo_AesCmacKey.Size(m)
}
func (m *AesCmacKey) XXX_DiscardUnknown() {
	xxx_messageInfo_AesCmacKey.DiscardUnknown(m)
}

var xxx_messageInfo_AesCmacKey proto.InternalMessageInfo

func (m *AesCmacKey) GetVersion() uint32 {
	if m != nil {
		return m.Version
	}
	return 0
}

func (m *AesCmacKey) GetKeyValue() []byte {
	if m != nil {
		return m.KeyValue
	}
	return nil
}

func (m *AesCmacKey) GetParams() *AesCmacParams {
	if m != nil {
		return m.Params
	}
	return nil
}

type AesCmacKeyFormat struct {
	KeySize              uint32         `protobuf:"varint,1,opt,name=key_size,json=keySize,proto3" json:"key_size,omitempty"`
	Params               *AesCmacParams `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"`
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
	XXX_unrecognized     []byte         `json:"-"`
	XXX_sizecache        int32          `json:"-"`
}

func (m *AesCmacKeyFormat) Reset()         { *m = AesCmacKeyFormat{} }
func (m *AesCmacKeyFormat) String() string { return proto.CompactTextString(m) }
func (*AesCmacKeyFormat) ProtoMessage()    {}
func (*AesCmacKeyFormat) Descriptor() ([]byte, []int) {
	return fileDescriptor_0723dd6d150a325c, []int{2}
}

func (m *AesCmacKeyFormat) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_AesCmacKeyFormat.Unmarshal(m, b)
}
func (m *AesCmacKeyFormat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_AesCmacKeyFormat.Marshal(b, m, deterministic)
}
func (m *AesCmacKeyFormat) XXX_Merge(src proto.Message) {
	xxx_messageInfo_AesCmacKeyFormat.Merge(m, src)
}
func (m *AesCmacKeyFormat) XXX_Size() int {
	return xxx_messageInfo_AesCmacKeyFormat.Size(m)
}
func (m *AesCmacKeyFormat) XXX_DiscardUnknown() {
	xxx_messageInfo_AesCmacKeyFormat.DiscardUnknown(m)
}

var xxx_messageInfo_AesCmacKeyFormat proto.InternalMessageInfo

func (m *AesCmacKeyFormat) GetKeySize() uint32 {
	if m != nil {
		return m.KeySize
	}
	return 0
}

func (m *AesCmacKeyFormat) GetParams() *AesCmacParams {
	if m != nil {
		return m.Params
	}
	return nil
}

func init() {
	proto.RegisterType((*AesCmacParams)(nil), "google.crypto.tink.AesCmacParams")
	proto.RegisterType((*AesCmacKey)(nil), "google.crypto.tink.AesCmacKey")
	proto.RegisterType((*AesCmacKeyFormat)(nil), "google.crypto.tink.AesCmacKeyFormat")
}

func init() {
	proto.RegisterFile("proto/aes_cmac.proto", fileDescriptor_0723dd6d150a325c)
}

var fileDescriptor_0723dd6d150a325c = []byte{
	// 271 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x90, 0xc1, 0x4b, 0xc3, 0x30,
	0x14, 0x87, 0x69, 0x85, 0x6e, 0x46, 0x07, 0x92, 0x53, 0x45, 0x0f, 0xb5, 0x20, 0x14, 0x0f, 0x29,
	0xe8, 0xc9, 0xa3, 0x13, 0x04, 0x19, 0x48, 0xa9, 0x22, 0xe8, 0x25, 0x64, 0xf1, 0x91, 0x86, 0x2e,
	0x7b, 0x25, 0xcd, 0x06, 0xd9, 0xc1, 0x3f, 0xc6, 0xbf, 0x54, 0x5a, 0x2b, 0x4e, 0xdc, 0xc5, 0xe3,
	0x2f, 0x7c, 0xe1, 0xfb, 0x78, 0xe4, 0xdc, 0x55, 0xda, 0xbe, 0xf1, 0x46, 0x58, 0xe7, 0x73, 0xa7,
	0x97, 0x75, 0xde, 0x58, 0x74, 0x98, 0x0b, 0x68, 0xb9, 0x34, 0x42, 0xb2, 0x7e, 0x52, 0xaa, 0x10,
	0xd5, 0x02, 0x98, 0xb4, 0xbe, 0x71, 0xc8, 0x3a, 0x30, 0xbd, 0x20, 0x93, 0x1b, 0x68, 0x6f, 0x8d,
	0x90, 0x85, 0xb0, 0xc2, 0xb4, 0xf4, 0x98, 0x8c, 0x9d, 0x50, 0xbc, 0xd5, 0x1b, 0x88, 0x83, 0x24,
	0xc8, 0x26, 0xe5, 0xc8, 0x09, 0xf5, 0xa8, 0x37, 0x90, 0xbe, 0x13, 0x32, 0xb0, 0x33, 0xf0, 0x34,
	0x26, 0xa3, 0x35, 0xd8, 0x56, 0xe3, 0xf2, 0x9b, 0x1b, 0x26, 0x3d, 0x21, 0xfb, 0x35, 0x78, 0xbe,
	0x16, 0x8b, 0x15, 0xc4, 0x61, 0x12, 0x64, 0x87, 0xe5, 0xb8, 0x06, 0xff, 0xdc, 0x6d, 0x7a, 0x4d,
	0xa2, 0xa6, 0x37, 0xc5, 0x7b, 0x49, 0x90, 0x1d, 0x5c, 0x9e, 0xb1, 0xbf, 0x55, 0xec, 0x57, 0x52,
	0x39, 0x7c, 0x48, 0x2b, 0x72, 0xf4, 0xe3, 0xbf, 0x43, 0x6b, 0x84, 0xeb, 0x72, 0x3b, 0xd7, 0x76,
	0x6e, 0x0d, 0xbe, 0xcb, 0xdd, 0x32, 0x85, 0xff, 0x34, 0x4d, 0x5f, 0xc8, 0xa9, 0x44, 0xb3, 0x8b,
	0xef, 0x2f, 0x59, 0x04, 0xaf, 0x4c, 0x69, 0x57, 0xad, 0xe6, 0x4c, 0xa2, 0xc9, 0xbf, 0xb0, 0x5d,
	0x87, 0xe7, 0x0a, 0x79, 0xff, 0xf2, 0x11, 0x46, 0x4f, 0xf7, 0x0f, 0xb3, 0x62, 0x3a, 0x8f, 0xfa,
	0x7d, 0xf5, 0x19, 0x00, 0x00, 0xff, 0xff, 0x5e, 0x57, 0xff, 0xca, 0xb4, 0x01, 0x00, 0x00,
}
