package crypto

import (
	 // #nosec
	
	
	

	
	
	
)

// See https://core.telegram.org/mtproto/description#defining-aes-key-and-initialization-vector

// Key represents 2048-bit authorization key value.
type Key [256]byte

func ( Key) () string {
	// Never print key.
	return "(redacted)"
}

// Zero reports whether Key is zero value.
func ( Key) () bool {
	return  == Key{}
}

// ID returns auth_key_id.
func ( Key) () [8]byte {
	 := sha1.Sum([:]) // #nosec
	var  [8]byte
	copy([:], [12:])
	return 
}

// AuxHash returns aux_hash value of key.
func ( Key) () [8]byte {
	 := sha1.Sum([:]) // #nosec
	var  [8]byte
	copy([:], [0:8])
	return 
}

// WithID creates new AuthKey from Key.
func ( Key) () AuthKey {
	return AuthKey{
		Value: ,
		ID:    .ID(),
	}
}

// AuthKey is a Key with cached id.
type AuthKey struct {
	Value Key
	ID    [8]byte
}

// DecodeJSON decode AuthKey from object with base64-encoded key and integer ID.
func ( *AuthKey) ( *jx.Decoder) error {
	return .ObjBytes(func( *jx.Decoder,  []byte) error {
		switch string() {
		case "value":
			,  := .Base64()
			if  != nil {
				return errors.Wrap(, "decode value")
			}
			copy(.Value[:], )
		case "id":
			,  := .Int64()
			if  != nil {
				return errors.Wrap(, "decode id")
			}
			.SetIntID()
		default:
			return .Skip()
		}

		return nil
	})
}

// UnmarshalJSON implements json.Unmarshaler.
func ( *AuthKey) ( []byte) error {
	return .DecodeJSON(jx.DecodeBytes())
}

// EncodeJSON encodes AuthKey as object with base64-encoded key and integer ID.
func ( AuthKey) ( *jx.Encoder) error {
	.ObjStart()
	.FieldStart("value")
	.Base64(.Value[:])
	.FieldStart("id")
	.Int64(.IntID())
	.ObjEnd()
	return nil
}

// MarshalJSON implements json.Marshaler.
func ( AuthKey) () ([]byte, error) {
	 := jx.GetEncoder()
	if  := .EncodeJSON();  != nil {
		return nil, 
	}
	return .Bytes(), nil
}

// Zero reports whether Key is zero value.
func ( AuthKey) () bool {
	return  == AuthKey{}
}

// IntID returns key fingerprint (ID) as int64.
func ( AuthKey) () int64 {
	return int64(binary.LittleEndian.Uint64(.ID[:]))
}

// SetIntID sets key fingerprint (ID) as int64.
func ( *AuthKey) ( int64) {
	binary.LittleEndian.PutUint64(.ID[:], uint64())
}

// String implements fmt.Stringer.
func ( AuthKey) () string {
	return fmt.Sprintf("Key(id: %x)", .ID)
}

// MarshalLogObject implements zap.ObjectMarshaler.
func ( AuthKey) ( zapcore.ObjectEncoder) error {
	.AddString("id", hex.EncodeToString(.ID[:]))
	return nil
}