Go Public and Symmetric Key? The Best of Both Worlds: ECIES

Many encryption systems are compromised because they generate their encryption key using a passphrase, and which can considerably reduce…

Go Public and Symmetric Key? The Best of Both Worlds: ECIES

Many encryption systems are compromised because they generate their encryption key using a passphrase, and which can considerably reduce the overall security infrastructure. A passphrase which is taken from a standard dictionary, for example, might reduce the key strength from 256 bits to just 20 bits (for a list of around one million words).

So we often use a key exchange method, such as ECDH (Elliptic Curve Diffie-Hellman) to negotiate a shared key, and where we can then use symmetric key encryption (such as AES or 3DES) to encrypt and decrypt. But we might be worried about a man-in-the-middle attack so we can use an Elliptic Curve Integrated Encryption Scheme (ECIES) to generate a shared key without the need for the Diffie-Hellman exchange.

The method basically starts with Alice created a random key (dA) and then selecting a point on an Elliptic Curve (typically, this is secp256k1), and then determining her public key which is:

QA = dA 𝗑 G

The public key (QA) is then passed to Bob who creates a random number (r) and then calculates R and S:

R = r 𝗑G

S = r 𝗑 QA

The S key is now used with a symmetric key algorithm to encrypt a message. Bob then sends the encrypted message along with R. Alice can then calculate the same key (S) with:

S = dA 𝗑 R

The method is illustrated here:

A sample run is [here]:

Text input: Testing 123
Private key: 88378db4514d430d268a7a3e0f208b64bec637f3ffbaf7f1d012e6fcd815c809
Public key: a220e2df9623cde9a8f53fa80b87d2554ebc4c068285ffb009894d0399a56308
Cipher: 5fc6a08f93d3df3f178226185b797661add24a14c22a6ab4c2c792826ba159976a99ba33a1566169bef836d0452d1b444ca9461a3e989cbe9ece3b
Decipher: Testing 123

The code is based on [here]:

package main
import (
"fmt"
"os"

    "go.dedis.ch/kyber/group/edwards25519"
"go.dedis.ch/kyber/util/random"
"go.dedis.ch/kyber/encrypt/ecies"
)
var rng = random.New()
func main() {
    m:="Hello"
    argCount := len(os.Args[1:])
        if (argCount>0) {m= string(os.Args[1])}

    message := []byte(m)
    suite := edwards25519.NewBlakeSHA256Ed25519()
    private := suite.Scalar().Pick(random.New())
    public := suite.Point().Mul(private, nil)
    ciphertext, _ := ecies.Encrypt(suite, public, message, suite.Hash)
    fmt.Printf("Text input: %s\n\n",m)
fmt.Printf("Private key: %s\n",private)
fmt.Printf("Public key: %s\n\n",public)
    fmt.Printf("Cipher: %x",ciphertext)
    plaintext, _ := ecies.Decrypt(suite, private, ciphertext, suite.Hash)
fmt.Printf("\n\nDecipher: %s",plaintext)
}

For NIST P-256, we just add:

import (
"go.dedis.ch/kyber/group/nist"
)
suite := nist.NewBlakeSHA256P256()

For BN256 pairing, we just add:

import (
"go.dedis.ch/kyber/pairing"
)
suite := pairing.NewSuiteBn256()

Conclusions

Whether it’s Blockchain, Tor, Bitcoin or IoT security, elliptic curve methods seem to be ruling the roost just now. While RSA still wins within digital certificates, it is elliptic curve methods that are winning in most other areas. While elliptic curve is typically used for signing data and for key exchange, we can see it can also be used to create a symmetric key which can then be applied to encrypt/decrypt a file using symmetric key methods. In this case I’ve used the AES encryption method, but you can apply many other method, if required.