\(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. In thhis case we will implement the SCK-1 method [2]
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. In thhis case we will implement the SCK-1 method [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\)). Next Alice sends \(aP\) as her public key and sends this to Bob. Bob sends \(bP\) as his public key to Alice.
The key for Alice is:
\(k_A=e(aQ_B,sP) \cdot e(sQ_A,bP) \)
The key for Bob is:
\(k_B=e(sQ_B,aP) \cdot e(bQ_A,sP) \)
and where \(sP\) is the public key generated from the KGC.
This works because:
\(k_A=e(aQ_B,sP) \cdot e(sQ_A,bP) = e(sQ_B,aP) \cdot e(bQ_A,sP)=k_B\)
We can also determine the key with:
\( K=e(aQ_B + bQ_A,sP) \)
The key is thus related to \(a,b,Q_A,Q_B,sP\).
This method is defined SCK (Smart-Chen-Kudla) and is defined as SCK-1 [2].
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) bQA:=BN254.G1mul(QA,b) sA:=BN254.G1mul(QA,s) QB := BN254.ECP_mapit(Q_B) aQB:=BN254.G1mul(QB,a) sB:=BN254.G1mul(QB,s) P := BN254.ECP2_generator() bP := BN254.G2mul(P,b) aP := BN254.G2mul(P,a) Ppub:=BN254.G2mul(P,s) // Alice uses a and sends aP to Bob // Bob uses b and sends bP to Alice // (aQb,sP)(sA,bP) // (aQb,sP)(sQA,bP) // (sQb,aP)(bQA,sP) // (sB,aP)(bQA,sP) LHS:=BN254.Ate(Ppub,aQB); LHS=BN254.Fexp(LHS) RHS2:=BN254.Ate(aP,sB); RHS2=BN254.Fexp(RHS2) LHS2:=BN254.Ate(bP,sA); LHS2=BN254.Fexp(LHS2) RHS:=BN254.Ate(Ppub,bQA); RHS=BN254.Fexp(RHS) RHS.Mul(RHS2) LHS.Mul(LHS2) 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()) fmt.Printf("\n\nPair 1 e(aQb,sP)e(sA,bP) - first 20 bytes:\t0x%x\n",FP12toByte(LHS)[:20]) fmt.Printf("Pair 2 e(sB,aP)e(bQA,sP) - first 20 bytes:\t0x%x\n",FP12toByte(RHS)[:20]) if LHS.Equals(RHS) { fmt.Printf("\nSecret match\n")} // e(aQB + bQA),sP) aQB.Add(bQA) key:=BN254.Ate(Ppub,aQB); key=BN254.Fexp(key) fmt.Printf("Key = e(aQB + bQA),sP) - first 20 bytes:\t0x%x\n",FP12toByte(key)[:20]) }
A sample run is:
Bob ID: bob@home Alice ID: alice@home Alice secret (a): 139136eaa21c4ba8fa261c6d17f6f272395ae41dd2c1f8c85d48bccf33c2460b Bob secret (b): 004f23ed49705f71ba2662275f20e6aa583b8d8150b46472303ad303ec655562 s: 0bd0bbdd2f79665802f7148e3b309bffb6288663e49cee22621d20759e4edaf6 QB: (24fe782588f174682f5eea7c6f9656dfa7a138814694a5594d38ea50aec70ed4,10da986194a99f6ed947e0831257ae2d52e957d2b5f7bf9205573a44d2062e68) QA: (12274944c48d83c874fe2fd6f5bac76cb2a9062b0edbcd2d6a7eda4cdc75ccc4,074dc393de05a5d44a979a7645932ebf9c4c6bfc27f6de6e2227163011985426) Pair 1 e(aQb,sP)e(sA,bP) - first 20 bytes: 0x08002b550a6ff942b2134afc03b97a78118a0390 Pair 2 e(sB,aP)e(bQA,sP) - first 20 bytes: 0x08002b550a6ff942b2134afc03b97a78118a0390 Secret match Key = e(aQB + bQA),sP) - first 20 bytes: 0x08002b550a6ff942b2134afc03b97a78118a0390
[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., Cheng, Z., & Smart, N. P. (2007). Identity-based key agreement protocols from pairings. International Journal of Information Security, 6(4), 213-241. [link]