Example #1
0
func keyPairFromTestCase(test ecTestCase) (*eckey.SecretKey, *eckey.PublicKey) {
	d, _ := new(big.Int).SetString(test.D, 10)
	x, _ := new(big.Int).SetString(test.X, 16)
	y, _ := new(big.Int).SetString(test.Y, 16)

	// Serialize secret key
	sk, _ := eckey.NewSecretKeyInt(d)

	// Serialize public key
	pk, _ := eckey.NewPublicKeyCoords(x, y)

	return sk, pk
}
Example #2
0
// Child computes the descendant of an HDKey at the specified child number.
func (k *HDKey) Child(i uint32) (*HDKey, error) {
	// Verify that child derivation is possible
	isChildHardened := i >= HardenedKeyStart
	if !k.IsPrivate() && isChildHardened {
		return nil, ErrDeriveHardenedFromPublic
	}

	// Assemble seed data for HMAC
	seed := make([]byte, childKeySize+childNumberSize)
	if isChildHardened {
		copy(seed, k[childKeyOffset:]) // Copy 0x00 || 32-byte secret key
	} else {
		copy(seed, k.CompressedPublicKey()[:]) // Copy HEADER || 32-byte X-coord
	}
	// Copy child number as uint32
	binary.BigEndian.PutUint32(seed[childKeySize:], i)

	// il, ir = HMAC-512(chainCode, seed), clean up intermediary state
	il, childChainCode := util.HMAC512Split(k.chainCode(), seed)
	defer func() { util.Zero(il); util.Zero(childChainCode) }()

	// Left 32 bytes becomes intermediate secret key, defer clean up
	ilInt := new(big.Int).SetBytes(il)
	defer ilInt.SetUint64(0)

	// Check that ilInt creates valid SecretKey, clean up intermediary SecretKey
	isk, err := eckey.NewSecretKeyInt(ilInt)
	if err != nil {
		return nil, ErrUnusableSeed
	}
	defer isk.Zero()

	ver := k.version()
	parentCPK := k.CompressedPublicKey()
	fpBytes := util.Hash256d(parentCPK[:])[:fingerprintSize]
	fp := binary.BigEndian.Uint32(fpBytes)

	// If key is private, derive a child secret key
	if k.IsPrivate() {
		sk := k.computeChildSecret(ilInt)
		return newHDSecretKey(ver, k.depth()+1, fp, i, childChainCode, sk), nil
	}

	// Otherwise, derive child public key
	cpk, err := computeChildPublic(parentCPK, isk)
	if err != nil {
		return nil, err
	}

	return newHDPublicKey(ver, k.depth()+1, fp, i, childChainCode, cpk), nil
}