예제 #1
0
func eciesEncrypt(rand io.Reader, pub *ecdsa.PublicKey, s1, s2 []byte, plain []byte) ([]byte, error) {
	params := pub.Curve

	// Select an ephemeral elliptic curve key pair associated with
	// elliptic curve domain parameters params
	priv, Rx, Ry, err := elliptic.GenerateKey(pub.Curve, rand)
	//fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes()))
	//fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes()))

	// Convert R=(Rx,Ry) to an octed string R bar
	// This is uncompressed
	Rb := elliptic.Marshal(pub.Curve, Rx, Ry)

	// Derive a shared secret field element z from the ephemeral secret key k
	// and convert z to an octet string Z
	z, _ := params.ScalarMult(pub.X, pub.Y, priv)
	Z := z.Bytes()
	//fmt.Printf("Z %s\n", utils.EncodeBase64(Z))

	// generate keying data K of length ecnKeyLen + macKeyLen octects from Z
	// ans s1
	kE := make([]byte, 32)
	kM := make([]byte, 32)
	hkdf := hkdf.New(conf.GetDefaultHash(), Z, s1, nil)
	_, err = hkdf.Read(kE)
	if err != nil {
		return nil, err
	}
	_, err = hkdf.Read(kM)
	if err != nil {
		return nil, err
	}

	// Use the encryption operation of the symmetric encryption scheme
	// to encrypt m under EK as ciphertext EM
	EM, err := aesEncrypt(kE, plain)

	// Use the tagging operation of the MAC scheme to compute
	// the tag D on EM || s2
	mac := hmac.New(conf.GetDefaultHash(), kM)
	mac.Write(EM)
	if len(s2) > 0 {
		mac.Write(s2)
	}
	D := mac.Sum(nil)

	// Output R,EM,D
	ciphertext := make([]byte, len(Rb)+len(EM)+len(D))
	//fmt.Printf("Rb %s\n", utils.EncodeBase64(Rb))
	//fmt.Printf("EM %s\n", utils.EncodeBase64(EM))
	//fmt.Printf("D %s\n", utils.EncodeBase64(D))
	copy(ciphertext, Rb)
	copy(ciphertext[len(Rb):], EM)
	copy(ciphertext[len(Rb)+len(EM):], D)

	return ciphertext, nil
}
예제 #2
0
파일: tca.go 프로젝트: yhjohn163/obc-peer
// CreateCertificateSet requests the creation of a new transaction certificate set by the TCA.
//
func (tcap *TCAP) CreateCertificateSet(ctx context.Context, in *pb.TCertCreateSetReq) (*pb.TCertCreateSetResp, error) {
	Trace.Println("grpc TCAP:CreateCertificateSet")

	id := in.Id.Id
	raw, err := tcap.tca.eca.readCertificate(id, x509.KeyUsageDigitalSignature)
	if err != nil {
		return nil, err
	}
	cert, err := x509.ParseCertificate(raw)
	if err != nil {
		return nil, err
	}
	pub := cert.PublicKey.(*ecdsa.PublicKey)

	sig := in.Sig
	in.Sig = nil

	r, s := big.NewInt(0), big.NewInt(0)
	r.UnmarshalText(sig.R)
	s.UnmarshalText(sig.S)

	hash := utils.NewHash()
	raw, _ = proto.Marshal(in)
	hash.Write(raw)
	if ecdsa.Verify(pub, hash.Sum(nil), r, s) == false {
		return nil, errors.New("signature does not verify")
	}

	nonce := make([]byte, 16) // 8 bytes rand, 8 bytes timestamp
	rand.Reader.Read(nonce[:8])
	binary.LittleEndian.PutUint64(nonce[8:], uint64(in.Ts.Seconds))

	mac := hmac.New(conf.GetDefaultHash(), tcap.tca.hmacKey)
	raw, _ = x509.MarshalPKIXPublicKey(pub)
	mac.Write(raw)
	kdfKey := mac.Sum(nil)

	num := int(in.Num)
	if num == 0 {
		num = 1
	}
	var set [][]byte

	for i := 0; i < num; i++ {
		tidx := []byte(strconv.Itoa(i))
		tidx = append(tidx[:], nonce[:]...)

		mac = hmac.New(conf.GetDefaultHash(), kdfKey)
		mac.Write([]byte{1})
		extKey := mac.Sum(nil)[:32]

		mac = hmac.New(conf.GetDefaultHash(), kdfKey)
		mac.Write([]byte{2})
		mac = hmac.New(conf.GetDefaultHash(), mac.Sum(nil))
		mac.Write(tidx)

		one := new(big.Int).SetInt64(1)
		k := new(big.Int).SetBytes(mac.Sum(nil))
		k.Mod(k, new(big.Int).Sub(pub.Curve.Params().N, one))
		k.Add(k, one)

		tmpX, tmpY := pub.ScalarBaseMult(k.Bytes())
		txX, txY := pub.Curve.Add(pub.X, pub.Y, tmpX, tmpY)
		txPub := ecdsa.PublicKey{Curve: pub.Curve, X: txX, Y: txY}

		ext, err := CBCEncrypt(extKey, tidx)
		if err != nil {
			return nil, err
		}

		if raw, err = tcap.tca.createCertificate(id, &txPub, x509.KeyUsageDigitalSignature, in.Ts.Seconds, kdfKey, pkix.Extension{Id: TCertEncTCertIndex, Critical: true, Value: ext}); err != nil {
			Error.Println(err)
			return nil, err
		}
		set = append(set, raw)
	}

	return &pb.TCertCreateSetResp{&pb.CertSet{in.Ts, in.Id, kdfKey, set}}, nil
}
예제 #3
0
func eciesDecrypt(priv *ecdsa.PrivateKey, s1, s2 []byte, ciphertext []byte) ([]byte, error) {
	params := priv.Curve

	var (
		rLen   int
		hLen   int = conf.GetDefaultHash()().Size()
		mStart int
		mEnd   int
	)

	//fmt.Printf("Decrypt\n")
	switch ciphertext[0] {
	case 2, 3:
		rLen = ((priv.PublicKey.Curve.Params().BitSize + 7) / 8) + 1
		if len(ciphertext) < (rLen + hLen + 1) {
			return nil, errors.New("Invalid ciphertext")
		}
		break
	case 4:
		rLen = 2*((priv.PublicKey.Curve.Params().BitSize+7)/8) + 1
		if len(ciphertext) < (rLen + hLen + 1) {
			return nil, errors.New("Invalid ciphertext")
		}
		break

	default:
		return nil, errors.New("Invalid ciphertext")
	}

	mStart = rLen
	mEnd = len(ciphertext) - hLen
	//fmt.Printf("Rb %s\n", utils.EncodeBase64(ciphertext[:rLen]))

	Rx, Ry := elliptic.Unmarshal(priv.Curve, ciphertext[:rLen])
	if Rx == nil {
		return nil, errors.New("Invalid ephemeral PK")
	}
	if !priv.Curve.IsOnCurve(Rx, Ry) {
		return nil, errors.New("Invalid point on curve")
	}
	//fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes()))
	//fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes()))

	// Derive a shared secret field element z from the ephemeral secret key k
	// and convert z to an octet string Z
	z, _ := params.ScalarMult(Rx, Ry, priv.D.Bytes())
	Z := z.Bytes()
	//fmt.Printf("Z %s\n", utils.EncodeBase64(Z))

	// generate keying data K of length ecnKeyLen + macKeyLen octects from Z
	// ans s1
	kE := make([]byte, 32)
	kM := make([]byte, 32)
	hkdf := hkdf.New(conf.GetDefaultHash(), Z, s1, nil)
	_, err := hkdf.Read(kE)
	if err != nil {
		return nil, err
	}
	_, err = hkdf.Read(kM)
	if err != nil {
		return nil, err
	}

	// Use the tagging operation of the MAC scheme to compute
	// the tag D on EM || s2 and then compare
	mac := hmac.New(conf.GetDefaultHash(), kM)
	mac.Write(ciphertext[mStart:mEnd])
	if len(s2) > 0 {
		mac.Write(s2)
	}
	D := mac.Sum(nil)

	//fmt.Printf("EM %s\n", utils.EncodeBase64(ciphertext[mStart:mEnd]))
	//fmt.Printf("D' %s\n", utils.EncodeBase64(D))
	//fmt.Printf("D %s\n", utils.EncodeBase64(ciphertext[mEnd:]))
	if subtle.ConstantTimeCompare(ciphertext[mEnd:], D) != 1 {
		return nil, errors.New("Tag check failed")
	}

	// Use the decryption operation of the symmetric encryption scheme
	// to decryptr EM under EK as plaintext

	plaintext, err := aesDecrypt(kE, ciphertext[mStart:mEnd])

	return plaintext, err
}
예제 #4
0
// HMACTruncated hmacs x using key key and truncate to truncation
func HMACTruncated(key, x []byte, truncation int) []byte {
	mac := hmac.New(conf.GetDefaultHash(), key)
	mac.Write(x)

	return mac.Sum(nil)[:truncation]
}
예제 #5
0
// HMAC hmacs x using key key
func HMAC(key, x []byte) []byte {
	mac := hmac.New(conf.GetDefaultHash(), key)
	mac.Write(x)

	return mac.Sum(nil)
}
예제 #6
0
// NewHash returns a new hash function
func NewHash() hash.Hash {
	return conf.GetDefaultHash()()
}