예제 #1
0
파일: crypto.go 프로젝트: efaysal/etherapis
func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
	if len(pub) == 0 {
		return nil
	}
	x, y := elliptic.Unmarshal(secp256k1.S256(), pub)
	return &ecdsa.PublicKey{secp256k1.S256(), x, y}
}
예제 #2
0
파일: crypto.go 프로젝트: efaysal/etherapis
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
	s, err := Ecrecover(hash, sig)
	if err != nil {
		return nil, err
	}

	x, y := elliptic.Unmarshal(secp256k1.S256(), s)
	return &ecdsa.PublicKey{secp256k1.S256(), x, y}, nil
}
예제 #3
0
파일: crypto.go 프로젝트: efaysal/etherapis
// New methods using proper ecdsa keys from the stdlib
func ToECDSA(prv []byte) *ecdsa.PrivateKey {
	if len(prv) == 0 {
		return nil
	}

	priv := new(ecdsa.PrivateKey)
	priv.PublicKey.Curve = secp256k1.S256()
	priv.D = common.BigD(prv)
	priv.PublicKey.X, priv.PublicKey.Y = secp256k1.S256().ScalarBaseMult(prv)
	return priv
}
예제 #4
0
파일: rlpx.go 프로젝트: efaysal/etherapis
func decodeAuthMsg(prv *ecdsa.PrivateKey, token []byte, auth []byte) (*encHandshake, error) {
	var err error
	h := new(encHandshake)
	// generate random keypair for session
	h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil)
	if err != nil {
		return nil, err
	}
	// generate random nonce
	h.respNonce = make([]byte, shaLen)
	if _, err = rand.Read(h.respNonce); err != nil {
		return nil, err
	}

	msg, err := crypto.Decrypt(prv, auth)
	if err != nil {
		return nil, fmt.Errorf("could not decrypt auth message (%v)", err)
	}

	// decode message parameters
	// signature || sha3(ecdhe-random-pubk) || pubk || nonce || token-flag
	h.initNonce = msg[authMsgLen-shaLen-1 : authMsgLen-1]
	copy(h.remoteID[:], msg[sigLen+shaLen:sigLen+shaLen+pubLen])
	rpub, err := h.remoteID.Pubkey()
	if err != nil {
		return nil, fmt.Errorf("bad remoteID: %#v", err)
	}
	h.remotePub = ecies.ImportECDSAPublic(rpub)

	// recover remote random pubkey from signed message.
	if token == nil {
		// TODO: it is an error if the initiator has a token and we don't. check that.

		// no session token means we need to generate shared secret.
		// ecies shared secret is used as initial session token for new peers.
		// generate shared key from prv and remote pubkey.
		if token, err = h.ecdhShared(prv); err != nil {
			return nil, err
		}
	}
	signedMsg := xor(token, h.initNonce)
	remoteRandomPub, err := secp256k1.RecoverPubkey(signedMsg, msg[:sigLen])
	if err != nil {
		return nil, err
	}

	// validate the sha3 of recovered pubkey
	remoteRandomPubMAC := msg[sigLen : sigLen+shaLen]
	shaRemoteRandomPub := crypto.Sha3(remoteRandomPub[1:])
	if !bytes.Equal(remoteRandomPubMAC, shaRemoteRandomPub) {
		return nil, fmt.Errorf("sha3 of recovered ephemeral pubkey does not match checksum in auth message")
	}

	h.remoteRandomPub, _ = importPublicKey(remoteRandomPub)
	return h, nil
}
예제 #5
0
파일: node.go 프로젝트: efaysal/etherapis
// Pubkey returns the public key represented by the node ID.
// It returns an error if the ID is not a point on the curve.
func (id NodeID) Pubkey() (*ecdsa.PublicKey, error) {
	p := &ecdsa.PublicKey{Curve: secp256k1.S256(), X: new(big.Int), Y: new(big.Int)}
	half := len(id) / 2
	p.X.SetBytes(id[:half])
	p.Y.SetBytes(id[half:])
	if !p.Curve.IsOnCurve(p.X, p.Y) {
		return nil, errors.New("id is invalid secp256k1 curve point")
	}
	return p, nil
}
예제 #6
0
파일: asn1.go 프로젝트: efaysal/etherapis
func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve {
	switch {
	case curve.Equal(secgNamedCurveS256):
		return secp256k1.S256()
	case curve.Equal(secgNamedCurveP256):
		return elliptic.P256()
	case curve.Equal(secgNamedCurveP384):
		return elliptic.P384()
	case curve.Equal(secgNamedCurveP521):
		return elliptic.P521()
	}
	return nil
}
예제 #7
0
파일: asn1.go 프로젝트: efaysal/etherapis
func oidFromNamedCurve(curve elliptic.Curve) (secgNamedCurve, bool) {
	switch curve {
	case elliptic.P256():
		return secgNamedCurveP256, true
	case elliptic.P384():
		return secgNamedCurveP384, true
	case elliptic.P521():
		return secgNamedCurveP521, true
	case secp256k1.S256():
		return secgNamedCurveS256, true
	}

	return nil, false
}
예제 #8
0
파일: key.go 프로젝트: efaysal/etherapis
func NewKey(rand io.Reader) *Key {
	randBytes := make([]byte, 64)
	_, err := rand.Read(randBytes)
	if err != nil {
		panic("key generation: could not read from random source: " + err.Error())
	}
	reader := bytes.NewReader(randBytes)
	privateKeyECDSA, err := ecdsa.GenerateKey(secp256k1.S256(), reader)
	if err != nil {
		panic("key generation: ecdsa.GenerateKey failed: " + err.Error())
	}

	return NewKeyFromECDSA(privateKeyECDSA)
}
예제 #9
0
파일: key.go 프로젝트: efaysal/etherapis
// generate key whose address fits into < 155 bits so it can fit into
// the Direct ICAP spec. for simplicity and easier compatibility with
// other libs, we retry until the first byte is 0.
func NewKeyForDirectICAP(rand io.Reader) *Key {
	randBytes := make([]byte, 64)
	_, err := rand.Read(randBytes)
	if err != nil {
		panic("key generation: could not read from random source: " + err.Error())
	}
	reader := bytes.NewReader(randBytes)
	privateKeyECDSA, err := ecdsa.GenerateKey(secp256k1.S256(), reader)
	if err != nil {
		panic("key generation: ecdsa.GenerateKey failed: " + err.Error())
	}
	key := NewKeyFromECDSA(privateKeyECDSA)
	if !strings.HasPrefix(key.Address.Hex(), "0x00") {
		return NewKeyForDirectICAP(rand)
	}
	return key
}
예제 #10
0
파일: rlpx.go 프로젝트: efaysal/etherapis
func newInitiatorHandshake(remoteID discover.NodeID) (*encHandshake, error) {
	rpub, err := remoteID.Pubkey()
	if err != nil {
		return nil, fmt.Errorf("bad remoteID: %v", err)
	}
	// generate random initiator nonce
	n := make([]byte, shaLen)
	if _, err := rand.Read(n); err != nil {
		return nil, err
	}
	// generate random keypair to use for signing
	randpriv, err := ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil)
	if err != nil {
		return nil, err
	}
	h := &encHandshake{
		initiator:     true,
		remoteID:      remoteID,
		remotePub:     ecies.ImportECDSAPublic(rpub),
		initNonce:     n,
		randomPrivKey: randpriv,
	}
	return h, nil
}
예제 #11
0
파일: params.go 프로젝트: efaysal/etherapis
import (
	"crypto"
	"crypto/aes"
	"crypto/cipher"
	"crypto/elliptic"
	"crypto/sha256"
	"crypto/sha512"
	"fmt"
	"hash"

	"github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/crypto/secp256k1"
)

var (
	DefaultCurve                  = secp256k1.S256()
	ErrUnsupportedECDHAlgorithm   = fmt.Errorf("ecies: unsupported ECDH algorithm")
	ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
)

type ECIESParams struct {
	Hash      func() hash.Hash // hash function
	hashAlgo  crypto.Hash
	Cipher    func([]byte) (cipher.Block, error) // symmetric cipher
	BlockSize int                                // block size of symmetric cipher
	KeyLen    int                                // length of symmetric key
}

// Standard ECIES parameters:
// * ECIES using AES128 and HMAC-SHA-256-16
// * ECIES using AES256 and HMAC-SHA-256-32
예제 #12
0
파일: crypto.go 프로젝트: efaysal/etherapis
func GenerateKey() (*ecdsa.PrivateKey, error) {
	return ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
}
예제 #13
0
파일: crypto.go 프로젝트: efaysal/etherapis
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
	if pub == nil || pub.X == nil || pub.Y == nil {
		return nil
	}
	return elliptic.Marshal(secp256k1.S256(), pub.X, pub.Y)
}