Skip to content

Instantly share code, notes, and snippets.

@KhaosT
Created March 23, 2019 05:10
Show Gist options
  • Save KhaosT/73d56a3cd0496aefaa74c8e320602547 to your computer and use it in GitHub Desktop.
Save KhaosT/73d56a3cd0496aefaa74c8e320602547 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"encoding/binary"
"fmt"
)
func main() {
curve := elliptic.P256()
// ephemeral key
ephemeraPrivateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
fmt.Println(err)
return
}
ephemeralPublicKey := elliptic.Marshal(curve, ephemeraPrivateKey.X, ephemeraPrivateKey.Y)
otherPublicKeyBytes, _ := hex.DecodeString("0460292C66AC34D5E7EACAA90F750EF0930567172CED2A0EAAB8CB51C025BBA8DB82D0187A67361DDB742EDD9D65103B7FCED10A6A3372B7CB6CF1F001D97A690B")
otherPublicKeyX, otherPublicKeyY := elliptic.Unmarshal(curve, otherPublicKeyBytes)
// ECDH
x, _ := curve.ScalarMult(otherPublicKeyX, otherPublicKeyY, ephemeraPrivateKey.D.Bytes())
shared_key := x.Bytes()
// X963 KDF
length := 32
output := make([]byte, 0)
outlen := 0
counter := uint32(1)
for outlen < length {
h := sha256.New()
h.Write(shared_key) // Key Material: ECDH Key
counterBuf := make([]byte, 4)
binary.BigEndian.PutUint32(counterBuf, counter)
h.Write(counterBuf)
h.Write(ephemeralPublicKey) // Shared Info: Our public key
output = h.Sum(output)
outlen += h.Size()
counter += 1
}
// Key
encryptionKey := output[0:16]
iv := output[16:]
fmt.Println(hex.EncodeToString(encryptionKey))
fmt.Println(hex.EncodeToString(iv))
// AES
block, _ := aes.NewCipher(encryptionKey)
aesgcm, _ := cipher.NewGCMWithNonceSize(block, 16)
ct := aesgcm.Seal(nil, iv, []byte("Hello World"), nil)
fmt.Println(hex.EncodeToString(ephemeralPublicKey) + hex.EncodeToString(ct))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment