# How Does Bob Encrypt Data For Alice, Using Just Her Email Address?

## Go and encrypt …

So can you send me an encrypted message by just knowing my ID? Well, IBE (Identity Based Encryption) does this, and the MIRACL library is just perfect in implementing it. Basically atrust authority creates a secret from Alice’s ID, and then passes Alice’s private key using her ID and the secret value:

First we have two curves (G1 and G2) and initially we define a large prime number (q). We then use a special pairing function e() for two points (U and V):

and where U is a point on the G2 curve and V is a point on the G1 curve.

A trust server selects a point on the G2 curve (P), and generates a using a random number (s): sk=s. Next the trust server creates a public key with (and where P is a base point on the G1 curve):

This will be a point on the G1 curve. Bob then takes Alice’s ID and hashes it:

He then creates this as a point on the G2 curve:

This is Alice’s public key. The trust server sends Alice her private key:

Bob takes the plaintext message (M) and creates a random number (r). Next Bob creates the ciphertext of:

Alice then justs uses her private key (dA) and the ciphertext elements (C1, C2) to recover the message with:

dA is Alice’s private key (sQA), QA is her public key, ⊕ operator is EX-OR, and e() is the pairing function. This works because:

## Coding

The outline coding using the library from the MIRACL library [here] is

`package mainimport ("fmt" "github.com/miracl/core/go/core" "github.com/miracl/core/go/core/BN254" "math/rand" "time" "os")func FP12toByte(F *BN254.FP12) []byte {const MFS int = int(BN254.MODBYTES) var t [12 * MFS]byteF.ToBytes(t[:]) return(t[:])}func ECPtoByte(F *BN254.ECP2) []byte {const MFS int = int(BN254.MODBYTES) var t [12 * MFS]byteF.ToBytes(t[:],true) return(t[:])}func randval() *core.RAND {s1 := rand.NewSource(time.Now().UnixNano())    r1 := rand.New(s1)rng := core.NewRAND()    var raw [100]byte    for i := 0; i < 100; i++ {       raw[i] = byte(r1.Intn(255))    }    rng.Seed(100, raw[:])    return rng}func xor(a []byte, b []byte) []byte{for i := 0;  i < len(a); i++ {  a[i]=(a[i]^b[i]) & 0xff }return a}func main() {AliceID:="myaddress" msg:="Hello"argCount := len(os.Args[1:])if (argCount>1) {msg= os.Args[1]}        if (argCount>2) {AliceID= os.Args[2]}q := BN254.NewBIGints(BN254.CURVE_Order)s:=BN254.Randomnum(q,randval()) r:=BN254.Randomnum(q,randval())sh:=core.NewHASH256() for i:=0;i < len(AliceID);i++ {  sh.Process(AliceID[i]) } Q_A:=sh.Hash()QA := BN254.ECP2_mapit(Q_A)// Alice's secret key: dA dA:=BN254.G2mul(QA,s)P := BN254.ECP_generator() sP:=BN254.G1mul(P,s)M := []byte(msg)pair:=BN254.Ate(QA,sP);  pair=BN254.Fexp(pair) pair=pair.Pow(r)C1:=BN254.G1mul(P,r)C2:=xor(M,FP12toByte(pair))pair2:=BN254.Ate(dA,C1);  pair2=BN254.Fexp(pair2)fmt.Printf("Message:\t%s\n\n",msg) fmt.Printf("Alice ID:\t%s\n\n",AliceID) fmt.Printf("Alice QA:\t%s\n\n",QA.ToString()) fmt.Printf("Alice private:\t%s\n\n",dA.ToString()) fmt.Printf("s:\t%s\n",s.ToString()) fmt.Printf("r:\t%s\n\n",r.ToString())fmt.Printf("C1:\t%s\n",C1.ToString()) fmt.Printf("C2:\t%x\n\n",C2)Cres:=xor(C2,FP12toByte(pair2))fmt.Printf("Decrypt: %s\n\n",Cres)fmt.Printf("\nPairing 1 e(QA,sP)^r:\t%x\n",FP12toByte(pair)[:20]) fmt.Printf("Pairing 2 e(dA,C1):\t%x\n\n",FP12toByte(pair2)[:20])}`

A sample run is [here]:

`Message: HelloAlice ID: myaddressAlice QA: ([22f89695210305ac8cc6f6e3b3f25564127746368f561b0a3d78838655678a04,098626898fd16868774246bd593faf156d659774febc5ff33cc3867ac07909fc],[1dd702f4a45bf6a247f6a5bb71c96d528beeb6860cc9e66baabfe25815ad2e10,130d4187e10b25ac3b6d6bc00bd433bcb02f676777e716f88cf5c3b998f1cb8d])Alice private: ([030f8ef338489ca72571bebba78fe68f02694da5f7681eddf051f90cf3b49e68,0b62b9e4f27eff39eda74bfc6cfc806e28dd8c4708771f4b474e242314d3c774],[0b195563e2f33f8fbf614054ba7075d5a017d252b5d90b48c61b57b2283343b8,0bba11988e80bfb90b6bb7b097ec1584ebab49fa9303d1f68215d8fc3f46b8de])s: 12a1dd2f951ac291b81acdc6cb9d506a3add0a8c1eb826e53f018d6b9a6673a0r: 003a0f064288945a929324d5706c5ead13959e4995cb3df0c7ca8326942a80d4C1: (098c71ac9f313cb903726cacb1879ff001d078deccc5fd7b0298c1d7e499a68a,0e8f3524936a078417f7dae4d6e562c3ff9bd2f89dedf8f80e0dcab168369f5f)C2: 468f2ef773Decrypt: HelloPairing 1 e(QA,sP)^r: 0eea429b1c0d4d505706dbd47641af6a2109dcaePairing 2 e(dA,C1): 0eea429b1c0d4d505706dbd47641af6a2109dcae`

## Conclusions

For IoT infrastructures, PKI is just not scalable, and so IBE may fit better.

Written by