// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package x509

import (
	
	
	
	
	
	
)

const ecPrivKeyVersion = 1

// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
// References:
//
//	RFC 5915
//	SEC1 - http://www.secg.org/sec1-v2.pdf
//
// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
// most cases it is not.
type ecPrivateKey struct {
	Version       int
	PrivateKey    []byte
	NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
	PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"`
}

// ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form.
//
// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
func ( []byte) (*ecdsa.PrivateKey, error) {
	return parseECPrivateKey(nil, )
}

// MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form.
//
// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
// For a more flexible key format which is not EC specific, use
// [MarshalPKCS8PrivateKey].
func ( *ecdsa.PrivateKey) ([]byte, error) {
	,  := oidFromNamedCurve(.Curve)
	if ! {
		return nil, errors.New("x509: unknown elliptic curve")
	}

	return marshalECPrivateKeyWithOID(, )
}

// marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format and
// sets the curve ID to the given OID, or omits it if OID is nil.
func marshalECPrivateKeyWithOID( *ecdsa.PrivateKey,  asn1.ObjectIdentifier) ([]byte, error) {
	,  := .Bytes()
	if  != nil {
		return nil, 
	}
	,  := .PublicKey.Bytes()
	if  != nil {
		return nil, 
	}
	return asn1.Marshal(ecPrivateKey{
		Version:       1,
		PrivateKey:    ,
		NamedCurveOID: ,
		PublicKey:     asn1.BitString{Bytes: },
	})
}

// marshalECDHPrivateKey marshals an EC private key into ASN.1, DER format
// suitable for NIST curves.
func marshalECDHPrivateKey( *ecdh.PrivateKey) ([]byte, error) {
	return asn1.Marshal(ecPrivateKey{
		Version:    1,
		PrivateKey: .Bytes(),
		PublicKey:  asn1.BitString{Bytes: .PublicKey().Bytes()},
	})
}

// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
// The OID for the named curve may be provided from another source (such as
// the PKCS8 container) - if it is provided then use this instead of the OID
// that may exist in the EC private key structure.
func parseECPrivateKey( *asn1.ObjectIdentifier,  []byte) ( *ecdsa.PrivateKey,  error) {
	var  ecPrivateKey
	if ,  := asn1.Unmarshal(, &);  != nil {
		if ,  := asn1.Unmarshal(, &pkcs8{});  == nil {
			return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
		}
		if ,  := asn1.Unmarshal(, &pkcs1PrivateKey{});  == nil {
			return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
		}
		return nil, errors.New("x509: failed to parse EC private key: " + .Error())
	}
	if .Version != ecPrivKeyVersion {
		return nil, fmt.Errorf("x509: unknown EC private key version %d", .Version)
	}

	var  elliptic.Curve
	if  != nil {
		 = namedCurveFromOID(*)
	} else {
		 = namedCurveFromOID(.NamedCurveOID)
	}
	if  == nil {
		return nil, errors.New("x509: unknown elliptic curve")
	}

	 := (.Params().N.BitLen() + 7) / 8
	 := make([]byte, )

	// Some private keys have leading zero padding. This is invalid
	// according to [SEC1], but this code will ignore it.
	for len(.PrivateKey) > len() {
		if .PrivateKey[0] != 0 {
			return nil, errors.New("x509: invalid private key length")
		}
		.PrivateKey = .PrivateKey[1:]
	}

	// Some private keys remove all leading zeros, this is also invalid
	// according to [SEC1] but since OpenSSL used to do this, we ignore
	// this too.
	copy([len()-len(.PrivateKey):], .PrivateKey)

	return ecdsa.ParseRawPrivateKey(, )
}