\(\hat{e}(aU,bV) = \hat{e}(U,V)^{ab} = \hat{e}(abU, V) = \hat{e}(U, abV ) = \hat{e}(bU,aV)\)
In this case we will use Alice's ID and a secret to encrypt a message for her, and use the MIRACL library.
Encryption using Pairing-based cryptography Identity Based Encryption (IBE)
[MIRACL Home][Home]
With pairing-based cryptography we have two cyclic groups (\(G_1\) and \(G_2\)), and which are of an order of a prime number (\(n\)). A pairing on \((G_1,G_2,G_T)\) defines the function \(e:G_1 \times G_2 \rightarrow G_T\), and where \(g_1\) is a generator for \(G_1\) and \(g_2\) is a generator for \(G_2\). If \(U\) is a point on \(G_1\), and \(V\) is a point on \(G_2\), we have following rules:
\(\hat{e}(aU,bV) = \hat{e}(U,V)^{ab} = \hat{e}(abU, V) = \hat{e}(U, abV ) = \hat{e}(bU,aV)\) In this case we will use Alice's ID and a secret to encrypt a message for her, and use the MIRACL library. |
First we have two curves (\(G_1\) and \(G_2\)) and initially we define a large prime number (\(q\)). First a trust server selects a point on the \(G_2\) curve (\(P\)), and generates a using a random number (\(s\)):
\(sk=s\)
Next the trust server creates a public key with:
\(P_{pub}=sP\)
This will be a point on the \(G_1\) curve.
Bob takes takes Alice's ID and also hashes it:
\(ID=H(AliceID)\)
He then creates this as a point on the \(G_2\) curve:
\(Q_{A}=H_1(ID)\)
This is Alice's public key.
The trust server sends Alice her private key:
\(d_{A}=sQ_A\)
Bob takes the plaintext message (M) and create a random number (\(r\)). Next Bob creates the ciphertext of:
\(C=(rP, M \oplus H_2(\hat{e}(Q_A,P_{pub})^r))\)
Alice decrypts using \((C_1,C_2)\) with:
\(M=C_2 \oplus \hat{e}(d_A,C_1)\)
and where \(d_A\) is Alice's private key, and \(Q_A\) is her public key. The \(\oplus\) operator is EX-OR and \(\hat{e}()\) is the pairing function.
This is because:
\(\hat{e}(d_A,C_1) = \hat{e}(d_A,rP) = \hat{e}(sQ_A,rP) = \hat{e}{(sQ_A,P)}^r = \hat{e}{(Q_A,sP)}^r = \hat{e}{(Q_A,P_{pub})}^r \)
The outline coding using the library from the MIRACL library [here] is
package main import ( "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]byte F.ToBytes(t[:]) return(t[:]) } func ECPtoByte(F *BN254.ECP2) []byte { const MFS int = int(BN254.MODBYTES) var t [12 * MFS]byte F.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>0) {msg= os.Args[1]} if (argCount>1) {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:
Message: Hello Alice ID: alice@home Alice QA: ([08acf1c0839a47e7e474b48dc2db9c5771825fd7f21405ba7e3c5150ced08090,219e710f6f36208bbb199775f24ba38bf310bb870eb78ce778f2217550251a71],[0d14f733a49935e739052e6418d0e457e0d2d2caafbe38455a48ba42ff9b998a,1f4b102d2a138f36f8a5f000eacb7dfcc683ee78ca7820821eef1519129b40c6]) Alice private: ([02b60d705b12bec85749b54c2b430f91477a5f352275fc80d13ed080250e73cf,17002c17b3dcb0df9aed09cc9c42e36aaef8b46efce08e91b4b3e1746f0bbed8],[24a41f6b6b03c0c246ee9eb15f1c1bb93bff14716aa8f3cb5a802eee7ded71ea,0aa4ac4d1ea1a291f2e55e524d47cc5305add05c959cc1816d011f1efc85d57a]) s: 23ab1e3732f4e2a1eeb54e9376c3dd6e407e4b230090963a06d32c74862dd531 r: 0eb87e815abc73b57dda01a835e06d88c27cb5ee0b4129a4d2d62bfddb7e94c6 C1: (11b5f2cabc94430e86b1f07846ffe57b61173a27e3aefe6d0484f7524c85b86b,23d9431ce75281713277a171e06d0b3b23b8245d5ff4201cb4bf057c0530936a) C2: 4719b1ea20 Decrypt: Hello Pairing 1 e(QA,sP)^r: 0f7cdd864f862eca0afe423008d445aac0151139 Pairing 2 e(dA,C1): 0f7cdd864f862eca0afe423008d445aac0151139