If \(U\) is a point on \(G_1\), and \(V\) is a point on \(G_2\), we get:
\(e(aU,V) = e(U,aV)\)
The shared key for Alice is \(e(id_a,P_b)\) and for Bob it is \(e(id_b,P_a)\).
Pairing-based cryptography ID-based AKE (Authenticated Key Exchange) with MIRACL
[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 get: \(e(aU,V) = e(U,aV)\) The shared key for Alice is \(e(id_a,P_b)\) and for Bob it is \(e(id_b,P_a)\). |
In non-interactive Identity-Based AKE (Authenticated Key Exchange), we have a trusted server in which Alice and Bob are registered with their identity.
The trusted server initially creates a secret key (\(s\)), and Bob generates his ID with (\(id_b)\) and Alice with (\(id_a\)). Next the server generates Bob's public key (\(P_b\)) with (\(s \times id_b\)) and Alice's public key (\(P_a\)) with (\(s \times id_a\)). Alice receives \(P_b\), and Bob receives \(P_a\). The shared key for Alice is \(e(id_a,P_b)\) and for Bob it is \(e(id_b,P_a)\). This is because:
\(e(id_a,P_b)\) = \(e(id_a,s \times id_b)\) = \(e(s \times id_a, id_b)\) = \(e(P_a,id_b)\)
The outline coding using the library from the MIRACL library [here] is
package main import ( "fmt" "github.com/miracl/core/go/core/BN254" "os" "strconv" ) func FP12toByte(F *BN254.FP12) []byte { const MFS int = int(BN254.MODBYTES) var t [12 * MFS]byte F.ToBytes(t[:]) return(t[:]) } func main() { PbobID:=10 PaliceID:=43 s:=31 // Secret server key argCount := len(os.Args[1:]) if (argCount>0) {PbobID,_= strconv.Atoi(os.Args[1])} if (argCount>1) {PaliceID,_= strconv.Atoi(os.Args[2])} if (argCount>2) {s,_= strconv.Atoi(os.Args[3])} U := BN254.ECP_generator() V := BN254.ECP2_generator() // Alice private and public priv_a:=BN254.G1mul(U,BN254.NewBIGint(s*PaliceID)) id_a:=BN254.G2mul(V,BN254.NewBIGint(PaliceID)) // Bob private and public priv_b:=BN254.G1mul(U,BN254.NewBIGint(s*PbobID)) id_b:=BN254.G2mul(V,BN254.NewBIGint(PbobID)) key_alice := BN254.Ate(id_b,priv_a) key_alice = BN254.Fexp(key_alice) key_bob := BN254.Ate(id_a,priv_b) key_bob = BN254.Fexp(key_bob) fmt.Printf("\nBob ID: %d, Alice ID: %d, Secret: %d\n",PbobID,PaliceID,s) fmt.Printf("\nPairing: %s\n",key_alice.ToString()) fmt.Printf("\nBob Key (first 20 bytes):\t0x%x\n",FP12toByte(key_bob)[:20]) fmt.Printf("Alice Key (first 20 bytes):\t0x%x\n",FP12toByte(key_alice)[:20]) if key_bob.Equals(key_alice) { fmt.Printf("\nPairing 1 [e(id_b,pub_a)] is equal to Pairing 2 [e(id_a,pub_b)]")} }
A sample run:
Bob ID: 10, Alice ID: 50, Secret: 99 Pairing: [[[0418a239ce3b927fc5312a572bebb03f18a78925425cb6c6e007151f668a89db, 15676e34a65895c9a5dbecf948b158cd810e619190dc207e787eecf923698362], [0b9e774125c980140322da2dbcde6045eed78463cdca0a9c41e086a871ae45ff, 005e3e78a5448071b57df556d2c76f8d45ae48ac5c325217735d74aa7e9e897a]], [[154d65ecc0ba2bd35043a402582ca6db60f298a4e1b4838ed507593654735ee4, 2379aced78e6097fc2306ed4b292250467ea91369efd22220c466c787bda6a66], [0706b1872913b025a53ad0d3e2b0d9a2eaffa6c3389e344cbc4a38f4474345af, 0d21ad4bdb03f54ecfe4d87adbf3015ffae8fc40a965848665d7aab209feb117]], [[010ecffc3e93f9b38516b80bfdcf177425cb09b84ffe1157e1cf4ff30cbc7b27, 1fb44b3d76ea5938150c6b402bfe37b7c08890b8ca324c532761bac0b60c9127], [149afbbcc801cddec28e59c5029c38ff50b77835a8c6aa92df35eb487dc5fb3e, 0725e2004c923cdc727637b194deb7d5f83f0d127632eac8208633b8600ada5d]]] Bob Key (first 20 bytes): 0x0418a239ce3b927fc5312a572bebb03f18a78925 Alice Key (first 20 bytes): 0x0418a239ce3b927fc5312a572bebb03f18a78925 Pairing 1 [e(id_b,pub_a)] is equal to Pairing 2 [e(id_a,pub_b)]