\(e(aU,bV) = e(U,V)^{ab} = e(abU, V) = e(U, abV ) = e(bU,aV)\)
In this case we will use Bob and Alice's ID to generate a secret shared key, and use the MIRACL library. It uses the method proposed by Chen [2].
Enhanced Identity-based (authenticated) key agreement
[Pairing 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:
\(e(aU,bV) = e(U,V)^{ab} = e(abU, V) = e(U, abV ) = e(bU,aV)\) In this case we will use Bob and Alice's ID to generate a secret shared key, and use the MIRACL library. It uses the method proposed by Chen [2]. |
First we have two curves (\(G_1\) and \(G_2\)) and initially we define a large prime number (\(q\)). Initially the KGC (Key Generation Centre) creates a secret random value (\(s\)) and shares it with Bob and Alice. We then have a known ID for Bob (\(ID_{bob}\)) and for Alice (\(ID_{alice}\)). Their public key will then become the hash of these values mapped to a curve:
\(Q_A = H(ID_A)\)
\(Q_B = H(ID_B)\)
Alice generates a secret value for the secret sharing (\(a\)) and Bob generates his own secret (\(b\)).
The KGC generates a secret (\(s\)). Bob sends his public key \(bQ_B\) to Alice, and Alice send her public key of \(aQ_A\).
The key for Alice is:
\(K_A=e(sA, bQ_B+aQ_B)\)
Bob computes:
\(K_B=e(aQ_A+bQ_A, sB)\)
This works because:
\(K_A=e(SA, W_B+aQB) = e(sQA,W_B) \cdot e(sA,aQB) = e(sQA,bQB) \cdot e(sQa,aQB) = e(bQA,sQB) \cdot e(sQa,sQB) = e(bQA+sQa,sQB) = e(sB,W_A+bQA) = K_B\)
and where \(W_A=aQ_A\) is Alice's public key, and \(W_B=bQ_B\) is Bob's public key.
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 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 main() { BobID:="athome" AliceID:="myaddress" argCount := len(os.Args[1:]) if (argCount>0) {BobID= (os.Args[1])} if (argCount>1) {AliceID= os.Args[2]} q := BN254.NewBIGints(BN254.CURVE_Order) s:=BN254.Randomnum(q,randval()) a:=BN254.Randomnum(q,randval()) b:=BN254.Randomnum(q,randval()) sh:=core.NewHASH256() for i:=0;i < len(BobID);i++ { sh.Process(BobID[i]) } Q_B:=sh.Hash() sh=core.NewHASH256() for i:=0;i < len(AliceID);i++ { sh.Process(AliceID[i]) } Q_A:=sh.Hash() QA := BN254.ECP_mapit(Q_A) Wa:=BN254.G1mul(QA,a) bQA:=BN254.G1mul(QA,b) sA:=BN254.G1mul(QA,s) QB := BN254.ECP2_mapit(Q_B) Wb:=BN254.G2mul(QB,b) aQB:=BN254.G2mul(QB,a) sB:=BN254.G2mul(QB,s) fmt.Printf("Bob ID:\t\t%s\n",BobID) fmt.Printf("Alice ID:\t%s\n\n",AliceID) fmt.Printf("Alice secret (a):\t%s\n\n",a.ToString()) fmt.Printf("Bob secret (b):\t\t%s\n\n",b.ToString()) fmt.Printf("s:\t%s\n\n",s.ToString()) fmt.Printf("QB:\t%s\n\n",QB.ToString()) fmt.Printf("QA:\t%s\n\n",QA.ToString()) // e(SA, WB+aQB) Wb.Add(aQB) key:=BN254.Ate(Wb,sA); key=BN254.Fexp(key) fmt.Printf("Key = e(SA, WB+aQB) - first 20 bytes:\t0x%x\n",FP12toByte(key)[:20]) // e(sB,WA+bQA) Wa.Add(bQA) key=BN254.Ate(sB,Wa); key=BN254.Fexp(key) fmt.Printf("Key = e(WA+bQA, SB)- first 20 bytes:\t0x%x\n",FP12toByte(key)[:20]) }
A sample run is:
Bob ID: bob@home Alice ID: alice@home Alice secret (a): 14e4a0bbac67e65154ffb1eca05c25f446f03b376343ef0ec9945fb8e11b8f86 Bob secret (b): 1b5ff8a43e3a501d674e60a4d5c346e33cf10152042419d6d80ea2869363ef8d s: 18fe47a961118c9bb7b0a103fbce112dddbde26ba075414ac3f861c7e7b89634 QB: ([0e0c27fda99a9cebb9b647a99e3c3821ca7512ba40251577010f3d284ec5dce4,0739f52acb074f77826a1fd05e0ecb44f4e6ad38274f4d691a5ab55e97b15dd0],[0fc2a977d7e1ccfa2c070180855ea532c2c4da3538cda2bdab733c0f26e5e112,030ee76d93b45c313f43e15ddaf2fd301f9ca6ce32b37981d93283ce76ad4f2b]) QA: (12274944c48d83c874fe2fd6f5bac76cb2a9062b0edbcd2d6a7eda4cdc75ccc4,074dc393de05a5d44a979a7645932ebf9c4c6bfc27f6de6e2227163011985426) Key = e(SA, WB+aQB) - first 20 bytes: 0x1854fddd953cebe3c0a526435e4a15ecf6b799e8 Key = e(WA+bQA, SB)- first 20 bytes: 0x1854fddd953cebe3c0a526435e4a15ecf6b799e8
[1] Smart, N. P. (2002). Identity-based authenticated key agreement protocol based on Weil pairing. Electronics letters, 38(13), 630-632. [link].
[2] Chen, L., & Kudla, C. (2003, June). Identity based authenticated key agreement protocols from pairings. In 16th IEEE Computer Security Foundations Workshop, 2003. Proceedings. (pp. 219-233). IEEE. [link]