// Copyright 2018-2024 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package nkeys

import (
	
	
	
	
)

// kp is the internal struct for a kepypair using seed.
type kp struct {
	seed []byte
}

// All seeds are 32 bytes long.
const seedLen = 32

// CreatePair will create a KeyPair based on the rand entropy and a type/prefix byte.
func ( PrefixByte) (KeyPair, error) {
	return CreatePairWithRand(, nil)
}

// CreatePair will create a KeyPair based on the rand reader and a type/prefix byte. rand can be nil.
func ( PrefixByte,  io.Reader) (KeyPair, error) {
	if  == PrefixByteCurve {
		return CreateCurveKeysWithRand()
	}
	, ,  := ed25519.GenerateKey()
	if  != nil {
		return nil, 
	}

	,  := EncodeSeed(, .Seed())
	if  != nil {
		return nil, 
	}
	return &kp{}, nil
}

// rawSeed will return the raw, decoded 64 byte seed.
func ( *kp) () ([]byte, error) {
	, ,  := DecodeSeed(.seed)
	return , 
}

// keys will return a 32 byte public key and a 64 byte private key utilizing the seed.
func ( *kp) () (ed25519.PublicKey, ed25519.PrivateKey, error) {
	,  := .rawSeed()
	if  != nil {
		return nil, nil, 
	}
	return ed25519.GenerateKey(bytes.NewReader())
}

// Wipe will randomize the contents of the seed key
func ( *kp) () {
	io.ReadFull(rand.Reader, .seed)
	.seed = nil
}

// Seed will return the encoded seed.
func ( *kp) () ([]byte, error) {
	return .seed, nil
}

// PublicKey will return the encoded public key associated with the KeyPair.
// All KeyPairs have a public key.
func ( *kp) () (string, error) {
	, ,  := DecodeSeed(.seed)
	if  != nil {
		return "", 
	}
	, ,  := ed25519.GenerateKey(bytes.NewReader())
	if  != nil {
		return "", 
	}
	,  := Encode(, )
	if  != nil {
		return "", 
	}
	return string(), nil
}

// PrivateKey will return the encoded private key for KeyPair.
func ( *kp) () ([]byte, error) {
	, ,  := .keys()
	if  != nil {
		return nil, 
	}
	return Encode(PrefixBytePrivate, )
}

// Sign will sign the input with KeyPair's private key.
func ( *kp) ( []byte) ([]byte, error) {
	, ,  := .keys()
	if  != nil {
		return nil, 
	}
	return ed25519.Sign(, ), nil
}

// Verify will verify the input against a signature utilizing the public key.
func ( *kp) ( []byte,  []byte) error {
	, ,  := .keys()
	if  != nil {
		return 
	}
	if !ed25519.Verify(, , ) {
		return ErrInvalidSignature
	}
	return nil
}

// Seal is only supported on CurveKeyPair
func ( *kp) ( []byte,  string) ([]byte, error) {
	return nil, ErrInvalidNKeyOperation
}

// SealWithRand is only supported on CurveKeyPair
func ( *kp) ( []byte,  string,  io.Reader) ([]byte, error) {
	return nil, ErrInvalidNKeyOperation
}

// Open is only supported on CurveKey
func ( *kp) ( []byte,  string) ([]byte, error) {
	return nil, ErrInvalidNKeyOperation
}