예제 #1
0
파일: crypto.go 프로젝트: gitreview/ampify
// An implementation of PBKDF2 (Password-Based Key Derivation Function 2) as
// specified in PKCS #5 v2.0 from RSA Laboratorie and in `RFC 2898
// <http://www.ietf.org/rfc/rfc2898.txt>`.
func PBKDF2(hashfunc func([]byte) hash.Hash, password, salt []byte, iterations, keylen int) (key []byte) {

	var (
		digest          []byte
		i, j, k, length int
	)

	key = make([]byte, keylen)
	slice := key

	hash := hashfunc(password)
	hashlen := hash.Size()
	scratch := make([]byte, 4)

	for keylen > 0 {

		if hashlen > keylen {
			length = keylen
		} else {
			length = hashlen
		}

		i += 1

		scratch[0] = byte(i >> 24)
		scratch[1] = byte(i >> 16)
		scratch[2] = byte(i >> 8)
		scratch[3] = byte(i)

		hash.Write(salt)
		hash.Write(scratch)

		digest = hash.Sum()
		hash.Reset()

		for j = 0; j < length; j++ {
			slice[j] = digest[j]
		}

		for k = 1; k < iterations; k++ {
			hash.Write(digest)
			digest = hash.Sum()
			for j = 0; j < length; j++ {
				slice[j] ^= digest[j]
			}
			hash.Reset()
		}

		keylen -= length
		slice = slice[length:]

	}

	return

}
예제 #2
0
// index returns the array index for the given data.
func (i *InverseBloomFilter) index(data []byte) uint32 {
	hash := i.hashPool.Get().(hash.Hash32)
	hash.Write(data)
	index := hash.Sum32() % uint32(i.capacity)
	hash.Reset()
	i.hashPool.Put(hash)
	return index
}
예제 #3
0
파일: ecies.go 프로젝트: karalabe/etherapis
// Encrypt encrypts a message using ECIES as specified in SEC 1, 5.1.
//
// s1 and s2 contain shared information that is not part of the resulting
// ciphertext. s1 is fed into key derivation, s2 is fed into the MAC. If the
// shared information parameters aren't being used, they should be nil.
func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err error) {
	params := pub.Params
	if params == nil {
		if params = ParamsFromCurve(pub.Curve); params == nil {
			err = ErrUnsupportedECIESParameters
			return
		}
	}
	R, err := GenerateKey(rand, pub.Curve, params)
	if err != nil {
		return
	}

	hash := params.Hash()
	z, err := R.GenerateShared(pub, params.KeyLen, params.KeyLen)
	if err != nil {
		return
	}
	K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
	if err != nil {
		return
	}
	Ke := K[:params.KeyLen]
	Km := K[params.KeyLen:]
	hash.Write(Km)
	Km = hash.Sum(nil)
	hash.Reset()

	em, err := symEncrypt(rand, params, Ke, m)
	if err != nil || len(em) <= params.BlockSize {
		return
	}

	d := messageTag(params.Hash, Km, em, s2)

	Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y)
	ct = make([]byte, len(Rb)+len(em)+len(d))
	copy(ct, Rb)
	copy(ct[len(Rb):], em)
	copy(ct[len(Rb)+len(em):], d)
	return
}
예제 #4
0
파일: ecies.go 프로젝트: karalabe/etherapis
// Decrypt decrypts an ECIES ciphertext.
func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err error) {
	if c == nil || len(c) == 0 {
		err = ErrInvalidMessage
		return
	}
	params := prv.PublicKey.Params
	if params == nil {
		if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil {
			err = ErrUnsupportedECIESParameters
			return
		}
	}
	hash := params.Hash()

	var (
		rLen   int
		hLen   int = hash.Size()
		mStart int
		mEnd   int
	)

	switch c[0] {
	case 2, 3, 4:
		rLen = ((prv.PublicKey.Curve.Params().BitSize + 7) / 4)
		if len(c) < (rLen + hLen + 1) {
			err = ErrInvalidMessage
			return
		}
	default:
		err = ErrInvalidPublicKey
		return
	}

	mStart = rLen
	mEnd = len(c) - hLen

	R := new(PublicKey)
	R.Curve = prv.PublicKey.Curve
	R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen])
	if R.X == nil {
		err = ErrInvalidPublicKey
		return
	}
	if !R.Curve.IsOnCurve(R.X, R.Y) {
		err = ErrInvalidCurve
		return
	}

	z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen)
	if err != nil {
		return
	}

	K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
	if err != nil {
		return
	}

	Ke := K[:params.KeyLen]
	Km := K[params.KeyLen:]
	hash.Write(Km)
	Km = hash.Sum(nil)
	hash.Reset()

	d := messageTag(params.Hash, Km, c[mStart:mEnd], s2)
	if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 {
		err = ErrInvalidMessage
		return
	}

	m, err = symDecrypt(rand, params, Ke, c[mStart:mEnd])
	return
}