This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch update-code
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto.git

commit c832da2c01e8a262428ea76c4528d4cd113ea900
Author: Kealan McCusker <[email protected]>
AuthorDate: Mon Apr 4 10:46:55 2016 +0100

    added MPIN Two go/cgo wrapper code
---
 go/src/github.com/miracl/amcl-cgo/crypto.go        | 128 ++++++++
 go/src/github.com/miracl/amcl-cgo/crypto_test.go   | 322 ++++++++++++++++++++
 go/src/github.com/miracl/amcl-go/crypto.go         |  31 ++
 go/src/github.com/miracl/amcl-go/crypto_test.go    | 324 ++++++++++++++++++++-
 .../github.com/miracl/examples-cgo/mpinTwoPass.go  | 227 +++++++++++++++
 .../github.com/miracl/examples-go/mpinTwoPass.go   |   2 +-
 .../{mpinTwoPass.go => mpinTwoPassWrap.go}         | 111 ++++---
 7 files changed, 1098 insertions(+), 47 deletions(-)

diff --git a/go/src/github.com/miracl/amcl-cgo/crypto.go 
b/go/src/github.com/miracl/amcl-cgo/crypto.go
index 37e9801..38ac3ad 100644
--- a/go/src/github.com/miracl/amcl-cgo/crypto.go
+++ b/go/src/github.com/miracl/amcl-cgo/crypto.go
@@ -647,3 +647,131 @@ func MPIN_printBinary(array []byte) {
        }
        fmt.Printf("\n")
 }
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set 
HID=HTID */
+func MPIN_SERVER_1_WRAP(date int, ID []byte) (HID, HTID []byte) {
+       // Form Octets
+       IDStr := string(ID)
+       IDOct := GetOctet(IDStr)
+       defer OCT_free(&IDOct)
+
+       HIDOct := GetOctetZero(G1S)
+       defer OCT_free(&HIDOct)
+       HTIDOct := GetOctetZero(G1S)
+       defer OCT_free(&HTIDOct)
+
+       C.MPIN_SERVER_1(C.int(date), &IDOct, &HIDOct, &HTIDOct)
+
+       // Convert octet to bytes
+       HID = OCT_toBytes(&HIDOct)
+       HTID = OCT_toBytes(&HTIDOct)
+
+       return
+}
+
+/* Implement step 2 of MPin protocol on server side */
+func MPIN_SERVER_2_WRAP(date int, HID []byte, HTID []byte, Y []byte, SS 
[]byte, U []byte, UT []byte, V []byte) (errorCode int, E, F []byte) {
+       // Form Octets
+       HIDStr := string(HID)
+       HIDOct := GetOctet(HIDStr)
+       defer OCT_free(&HIDOct)
+       HTIDStr := string(HTID)
+       HTIDOct := GetOctet(HTIDStr)
+       defer OCT_free(&HTIDOct)
+       YStr := string(Y)
+       YOct := GetOctet(YStr)
+       defer OCT_free(&YOct)
+       SSStr := string(SS)
+       SSOct := GetOctet(SSStr)
+       defer OCT_free(&SSOct)
+       UStr := string(U)
+       UOct := GetOctet(UStr)
+       defer OCT_free(&UOct)
+       UTStr := string(UT)
+       UTOct := GetOctet(UTStr)
+       defer OCT_free(&UTOct)
+       VStr := string(V)
+       VOct := GetOctet(VStr)
+       defer OCT_free(&VOct)
+
+       EOct := GetOctetZero(GTS)
+       defer OCT_free(&EOct)
+       FOct := GetOctetZero(GTS)
+       defer OCT_free(&FOct)
+       rtn := C.MPIN_SERVER_2(C.int(date), &HIDOct, &HTIDOct, &YOct, &SSOct, 
&UOct, &UTOct, &VOct, &EOct, &FOct)
+
+       errorCode = int(rtn)
+       E = OCT_toBytes(&EOct)
+       F = OCT_toBytes(&FOct)
+
+       return
+}
+
+/* Implement step 1 on client side of MPin protocol. Use GO code to generate 
random X */
+func MPIN_CLIENT_1_WRAP(date int, ID []byte, RNG *amcl.RAND, X []byte, PIN 
int, TOKEN []byte, TP []byte) (errorCode int, XOut, SEC, U, UT []byte) {
+       amcl.MPIN_RANDOM_GENERATE(RNG, X[:])
+       errorCode, XOut, SEC, U, UT = MPIN_CLIENT_1_C(date, ID[:], nil, X[:], 
PIN, TOKEN[:], TP[:])
+       return
+}
+
+/* Implement step 1 on client side of MPin protocol
+   When rng=nil the X value is externally generated
+*/
+func MPIN_CLIENT_1_C(date int, ID []byte, rng *C.csprng, X []byte, PIN int, 
TOKEN []byte, TP []byte) (errorCode int, XOut, SEC, U, UT []byte) {
+       // Form Octets
+       IDStr := string(ID)
+       IDOct := GetOctet(IDStr)
+       defer OCT_free(&IDOct)
+
+       XStr := string(X)
+       XOct := GetOctet(XStr)
+       defer OCT_free(&XOct)
+
+       TOKENStr := string(TOKEN)
+       TOKENOct := GetOctet(TOKENStr)
+       defer OCT_free(&TOKENOct)
+
+       TPStr := string(TP)
+       TPOct := GetOctet(TPStr)
+       defer OCT_free(&TPOct)
+
+       SECOct := GetOctetZero(G1S)
+       defer OCT_free(&SECOct)
+       UOct := GetOctetZero(G1S)
+       defer OCT_free(&UOct)
+       UTOct := GetOctetZero(G1S)
+       defer OCT_free(&UTOct)
+
+       rtn := C.MPIN_CLIENT_1(C.int(date), &IDOct, rng, &XOct, C.int(PIN), 
&TOKENOct, &SECOct, &UOct, &UTOct, &TPOct)
+
+       errorCode = int(rtn)
+       // Convert octet to bytes
+       XOut = OCT_toBytes(&XOct)
+       SEC = OCT_toBytes(&SECOct)
+       U = OCT_toBytes(&UOct)
+       UT = OCT_toBytes(&UTOct)
+
+       return
+}
+
+/* Implement step 2 on client side of MPin protocol */
+func MPIN_CLIENT_2_WRAP(X []byte, Y []byte, SEC []byte) (errorCode int, V 
[]byte) {
+       // Form Octets
+       XStr := string(X)
+       XOct := GetOctet(XStr)
+       defer OCT_free(&XOct)
+       YStr := string(Y)
+       YOct := GetOctet(YStr)
+       defer OCT_free(&YOct)
+       SECStr := string(SEC)
+       SECOct := GetOctet(SECStr)
+       defer OCT_free(&SECOct)
+
+       rtn := C.MPIN_CLIENT_2(&XOct, &YOct, &SECOct)
+
+       errorCode = int(rtn)
+       // Convert octet to bytes
+       V = OCT_toBytes(&SECOct)
+
+       return
+}
diff --git a/go/src/github.com/miracl/amcl-cgo/crypto_test.go 
b/go/src/github.com/miracl/amcl-cgo/crypto_test.go
index ebbacbb..454e943 100644
--- a/go/src/github.com/miracl/amcl-cgo/crypto_test.go
+++ b/go/src/github.com/miracl/amcl-cgo/crypto_test.go
@@ -766,3 +766,325 @@ func TestMPINFull(t *testing.T) {
        got = hex.EncodeToString(AES_KEY_CLIENT[:])
        assert.Equal(t, want, got, "Should be equal")
 }
+
+func TestTwoPassGoodPIN(t *testing.T) {
+       want := 0
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+
+       // Epoch time in days
+       date := 16660
+
+       // PIN variable to create token
+       PIN1 := 1234
+       // PIN variable to authenticate
+       PIN2 := 1234
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := amclgo.NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Generate Master Secret Share 2
+       _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+       // Generate server secret share 2
+       _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+       // Combine server secret shares
+       _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+       // Generate client secret share 1
+       _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+       // Generate client secret share 2
+       _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+       // Combine client secret shares
+       CS := make([]byte, G1S)
+       _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+       // Generate time permit share 1
+       _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+       // Generate time permit share 2
+       _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+       // Combine time permit shares
+       _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+       // Create token
+       _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+       // Client Pass 1
+       var X [EGS]byte
+       _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], PIN2, 
TOKEN[:], TP[:])
+
+       // Server Pass 1
+       HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+       _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Client Pass 2
+       _, V := MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+       // Server Pass 2
+       got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], V[:])
+       assert.Equal(t, want, got, "Should be equal")
+}
+
+func TestTwoPassBadPIN(t *testing.T) {
+       want := -19
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+
+       // Epoch time in days
+       date := 16660
+
+       // PIN variable to create token
+       PIN1 := 1234
+       // PIN variable to authenticate
+       PIN2 := 1235
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := amclgo.NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Generate Master Secret Share 2
+       _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+       // Generate server secret share 2
+       _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+       // Combine server secret shares
+       _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+       // Generate client secret share 1
+       _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+       // Generate client secret share 2
+       _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+       // Combine client secret shares
+       CS := make([]byte, G1S)
+       _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+       // Generate time permit share 1
+       _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+       // Generate time permit share 2
+       _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+       // Combine time permit shares
+       _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+       // Create token
+       _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+       // Client Pass 1
+       var X [EGS]byte
+       _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], PIN2, 
TOKEN[:], TP[:])
+
+       // Server Pass 1
+       HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+       _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Client Pass 2
+       _, V := MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+       // Server Pass 2
+       got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], V[:])
+       assert.Equal(t, want, got, "Should be equal")
+}
+
+func TestTwoPassBadToken(t *testing.T) {
+       want := -19
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+
+       // Epoch time in days
+       date := 16660
+
+       // PIN variable to create token
+       PIN1 := 1234
+       // PIN variable to authenticate
+       PIN2 := 1234
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := amclgo.NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Generate Master Secret Share 2
+       _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+       // Generate server secret share 2
+       _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+       // Combine server secret shares
+       _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+       // Generate client secret share 1
+       _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+       // Generate client secret share 2
+       _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+       // Combine client secret shares
+       CS := make([]byte, G1S)
+       _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+       // Generate time permit share 1
+       _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+       // Generate time permit share 2
+       _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+       // Combine time permit shares
+       _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+       // Create token
+       _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+       // Client Pass 1
+       var X [EGS]byte
+       _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], PIN2, 
TOKEN[:], TP[:])
+
+       // Server Pass 1
+       HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+       _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Client Pass 2
+       _, _ = MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+       // Server Pass 2
+       // Send UT as V to model bad token
+       got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], UT[:])
+       assert.Equal(t, want, got, "Should be equal")
+}
+
+func TestRandomTwoPass(t *testing.T) {
+       want := 0
+
+       for i := 0; i < nIter; i++ {
+
+               // Seed value for Random Number Generator (RNG)
+               seed := make([]byte, 16)
+               rand.Read(seed)
+               rng := amclgo.NewRAND()
+               rng.Seed(len(seed), seed)
+
+               // Epoch time in days
+               date := MPIN_today()
+
+               // PIN variable to create token
+               PIN1 := mathrand.Intn(10000)
+               // PIN variable to authenticate
+               PIN2 := PIN1
+
+               // Assign the End-User a random ID
+               ID := make([]byte, 16)
+               rand.Read(ID)
+
+               // Generate Master Secret Share 1
+               _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+               // Generate Master Secret Share 2
+               _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+               // Either Client or TA calculates Hash(ID)
+               HCID := MPIN_HASH_ID(ID)
+
+               // Generate server secret share 1
+               _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+               // Generate server secret share 2
+               _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+               // Combine server secret shares
+               _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+               // Generate client secret share 1
+               _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+               // Generate client secret share 2
+               _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+               // Combine client secret shares
+               CS := make([]byte, G1S)
+               _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+               // Generate time permit share 1
+               _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+               // Generate time permit share 2
+               _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+               // Combine time permit shares
+               _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+               // Create token
+               _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+               // Client Pass 1
+               var X [EGS]byte
+               _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], 
PIN2, TOKEN[:], TP[:])
+
+               // Server Pass 1
+               HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+               _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+               // Client Pass 2
+               _, V := MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+               // Server Pass 2
+               got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], 
SS[:], U[:], UT[:], V[:])
+               assert.Equal(t, want, got, "Should be equal")
+
+       }
+}
diff --git a/go/src/github.com/miracl/amcl-go/crypto.go 
b/go/src/github.com/miracl/amcl-go/crypto.go
index 8e34f9c..e2b8bbb 100644
--- a/go/src/github.com/miracl/amcl-go/crypto.go
+++ b/go/src/github.com/miracl/amcl-go/crypto.go
@@ -189,3 +189,34 @@ func XORBytes(a, b, c []byte) ([]byte, int) {
        }
        return dst[:], 0
 }
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set 
HID=HTID */
+func MPIN_SERVER_1_WRAP(date int, ID []byte) ([]byte, []byte) {
+       var HID [G1S]byte
+       var HTID [G1S]byte
+       MPIN_SERVER_1(date, ID, HID[:], HTID[:])
+       return HID[:], HTID[:]
+}
+
+/* Implement step 2 of MPin protocol on server side */
+func MPIN_SERVER_2_WRAP(date int, HID []byte, HTID []byte, Y []byte, SS 
[]byte, U []byte, UT []byte, V []byte) (int, []byte, []byte) {
+       var E [12 * EFS]byte
+       var F [12 * EFS]byte
+       errorCode := MPIN_SERVER_2(date, HID[:], HTID[:], Y[:], SS[:], U[:], 
UT[:], V[:], E[:], F[:])
+       return errorCode, E[:], F[:]
+}
+
+/* Implement step 1 on client side of MPin protocol */
+func MPIN_CLIENT_1_WRAP(date int, ID []byte, rng *RAND, X []byte, PIN int, 
TOKEN []byte, TP []byte) (int, []byte, []byte, []byte, []byte) {
+       var SEC [G1S]byte
+       var U [G1S]byte
+       var UT [G1S]byte
+       errorCode := MPIN_CLIENT_1(date, ID[:], rng, X[:], PIN, TOKEN[:], 
SEC[:], U[:], UT[:], TP[:])
+       return errorCode, X[:], SEC[:], U[:], UT[:]
+}
+
+/* Implement step 2 on client side of MPin protocol */
+func MPIN_CLIENT_2_WRAP(X []byte, Y []byte, SEC []byte) (int, []byte) {
+       errorCode := MPIN_CLIENT_2(X[:], Y[:], SEC[:])
+       return errorCode, SEC[:]
+}
diff --git a/go/src/github.com/miracl/amcl-go/crypto_test.go 
b/go/src/github.com/miracl/amcl-go/crypto_test.go
index 7fc169a..710204e 100644
--- a/go/src/github.com/miracl/amcl-go/crypto_test.go
+++ b/go/src/github.com/miracl/amcl-go/crypto_test.go
@@ -29,7 +29,7 @@ import (
        "github.com/stretchr/testify/assert"
 )
 
-const nIter int = 100
+const nIter int = 1000
 
 func TestCryptoGoodPIN(t *testing.T) {
        want := 0
@@ -870,3 +870,325 @@ func TestCryptoCombineKey(t *testing.T) {
        got := hex.EncodeToString(PIN[:])
        assert.Equal(t, want, got, "Should be equal")
 }
+
+func TestCryptoTwoPassGoodPIN(t *testing.T) {
+       want := 0
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+
+       // Epoch time in days
+       date := 16660
+
+       // PIN variable to create token
+       PIN1 := 1234
+       // PIN variable to authenticate
+       PIN2 := 1234
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Generate Master Secret Share 2
+       _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+       // Generate server secret share 2
+       _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+       // Combine server secret shares
+       _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+       // Generate client secret share 1
+       _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+       // Generate client secret share 2
+       _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+       // Combine client secret shares
+       CS := make([]byte, G1S)
+       _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+       // Generate time permit share 1
+       _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+       // Generate time permit share 2
+       _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+       // Combine time permit shares
+       _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+       // Create token
+       _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+       // Client Pass 1
+       var X [EGS]byte
+       _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], PIN2, 
TOKEN[:], TP[:])
+
+       // Server Pass 1
+       HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+       _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Client Pass 2
+       _, V := MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+       // Server Pass 2
+       got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], V[:])
+       assert.Equal(t, want, got, "Should be equal")
+}
+
+func TestCryptoTwoPassBadPIN(t *testing.T) {
+       want := -19
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+
+       // Epoch time in days
+       date := 16660
+
+       // PIN variable to create token
+       PIN1 := 1234
+       // PIN variable to authenticate
+       PIN2 := 1235
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Generate Master Secret Share 2
+       _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+       // Generate server secret share 2
+       _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+       // Combine server secret shares
+       _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+       // Generate client secret share 1
+       _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+       // Generate client secret share 2
+       _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+       // Combine client secret shares
+       CS := make([]byte, G1S)
+       _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+       // Generate time permit share 1
+       _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+       // Generate time permit share 2
+       _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+       // Combine time permit shares
+       _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+       // Create token
+       _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+       // Client Pass 1
+       var X [EGS]byte
+       _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], PIN2, 
TOKEN[:], TP[:])
+
+       // Server Pass 1
+       HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+       _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Client Pass 2
+       _, V := MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+       // Server Pass 2
+       got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], V[:])
+       assert.Equal(t, want, got, "Should be equal")
+}
+
+func TestCryptoTwoPassBadToken(t *testing.T) {
+       want := -19
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+
+       // Epoch time in days
+       date := 16660
+
+       // PIN variable to create token
+       PIN1 := 1234
+       // PIN variable to authenticate
+       PIN2 := 1234
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Generate Master Secret Share 2
+       _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+       // Generate server secret share 2
+       _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+       // Combine server secret shares
+       _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+       // Generate client secret share 1
+       _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+       // Generate client secret share 2
+       _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+       // Combine client secret shares
+       CS := make([]byte, G1S)
+       _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+       // Generate time permit share 1
+       _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+       // Generate time permit share 2
+       _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+       // Combine time permit shares
+       _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+       // Create token
+       _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+       // Client Pass 1
+       var X [EGS]byte
+       _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], PIN2, 
TOKEN[:], TP[:])
+
+       // Server Pass 1
+       HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+       _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+       // Client Pass 2
+       _, _ = MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+       // Server Pass 2
+       // Send UT as V to model bad token
+       got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], UT[:])
+       assert.Equal(t, want, got, "Should be equal")
+}
+
+func TestCryptoRandomTwoPass(t *testing.T) {
+       want := 0
+
+       for i := 0; i < nIter; i++ {
+
+               // Seed value for Random Number Generator (RNG)
+               seed := make([]byte, 16)
+               rand.Read(seed)
+               rng := NewRAND()
+               rng.Seed(len(seed), seed)
+
+               // Epoch time in days
+               date := MPIN_today()
+
+               // PIN variable to create token
+               PIN1 := mathrand.Intn(10000)
+               // PIN variable to authenticate
+               PIN2 := PIN1
+
+               // Assign the End-User a random ID
+               ID := make([]byte, 16)
+               rand.Read(ID)
+
+               // Generate Master Secret Share 1
+               _, MS1 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+               // Generate Master Secret Share 2
+               _, MS2 := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+               // Either Client or TA calculates Hash(ID)
+               HCID := MPIN_HASH_ID(ID)
+
+               // Generate server secret share 1
+               _, SS1 := MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+
+               // Generate server secret share 2
+               _, SS2 := MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+
+               // Combine server secret shares
+               _, SS := MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+
+               // Generate client secret share 1
+               _, CS1 := MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+
+               // Generate client secret share 2
+               _, CS2 := MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+
+               // Combine client secret shares
+               CS := make([]byte, G1S)
+               _, CS = MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+
+               // Generate time permit share 1
+               _, TP1 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+
+               // Generate time permit share 2
+               _, TP2 := MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+
+               // Combine time permit shares
+               _, TP := MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+
+               // Create token
+               _, TOKEN := MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+
+               // Client Pass 1
+               var X [EGS]byte
+               _, _, SEC, U, UT := MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], 
PIN2, TOKEN[:], TP[:])
+
+               // Server Pass 1
+               HID, HTID := MPIN_SERVER_1_WRAP(date, ID)
+               _, Y := MPIN_RANDOM_GENERATE_WRAP(rng)
+
+               // Client Pass 2
+               _, V := MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+
+               // Server Pass 2
+               got, _, _ := MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], 
SS[:], U[:], UT[:], V[:])
+               assert.Equal(t, want, got, "Should be equal")
+
+       }
+}
diff --git a/go/src/github.com/miracl/examples-cgo/mpinTwoPass.go 
b/go/src/github.com/miracl/examples-cgo/mpinTwoPass.go
new file mode 100644
index 0000000..63b541b
--- /dev/null
+++ b/go/src/github.com/miracl/examples-cgo/mpinTwoPass.go
@@ -0,0 +1,227 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package main
+
+import (
+       "encoding/hex"
+       "fmt"
+
+       amclcgo "github.com/miracl/amcl-cgo"
+       amclgo "github.com/miracl/amcl-go"
+)
+
+func main() {
+       // Assign the End-User an ID
+       IDstr := "[email protected]"
+       ID := []byte(IDstr)
+       fmt.Printf("ID: ")
+       amclcgo.MPIN_printBinary(ID)
+       fmt.Printf("\n")
+
+       // Epoch time in days
+       date := amclcgo.MPIN_today()
+
+       // PIN variable to create token
+       PIN1 := -1
+       // PIN variable to authenticate
+       PIN2 := -1
+
+       // Seed value for Random Number Generator (RNG)
+       seedHex := "9e8b4178790cd57a5761c4a6f164ba72"
+       seed, err := hex.DecodeString(seedHex)
+       if err != nil {
+               fmt.Println("Error decoding seed value")
+               return
+       }
+       rng := amclgo.NewRAND()
+       rng.Seed(len(seed), seed)
+
+       // Generate Master Secret Share 1
+       rtn, MS1 := amclcgo.MPIN_RANDOM_GENERATE_WRAP(rng)
+       if rtn != 0 {
+               fmt.Println("MPIN_RANDOM_GENERATE Error:", rtn)
+               return
+       }
+       fmt.Printf("MS1: 0x")
+       amclcgo.MPIN_printBinary(MS1[:])
+
+       // Generate Master Secret Share 2
+       rtn, MS2 := amclcgo.MPIN_RANDOM_GENERATE_WRAP(rng)
+       if rtn != 0 {
+               fmt.Println("MPIN_RANDOM_GENERATE Error:", rtn)
+               return
+       }
+       fmt.Printf("MS2: 0x")
+       amclcgo.MPIN_printBinary(MS2[:])
+
+       // Either Client or TA calculates Hash(ID)
+       HCID := amclcgo.MPIN_HASH_ID(ID)
+
+       // Generate server secret share 1
+       rtn, SS1 := amclcgo.MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_SERVER_SECRET Error:", rtn)
+               return
+       }
+       fmt.Printf("SS1: 0x")
+       amclcgo.MPIN_printBinary(SS1[:])
+
+       // Generate server secret share 2
+       rtn, SS2 := amclcgo.MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_SERVER_SECRET Error:", rtn)
+               return
+       }
+       fmt.Printf("SS2: 0x")
+       amclcgo.MPIN_printBinary(SS2[:])
+
+       // Combine server secret shares
+       rtn, SS := amclcgo.MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_RECOMBINE_G2(SS1, SS2) Error:", rtn)
+               return
+       }
+       fmt.Printf("SS: 0x")
+       amclcgo.MPIN_printBinary(SS[:])
+
+       // Generate client secret share 1
+       rtn, CS1 := amclcgo.MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_SECRET Error:", rtn)
+               return
+       }
+       fmt.Printf("Client Secret Share CS1: 0x")
+       amclcgo.MPIN_printBinary(CS1[:])
+
+       // Generate client secret share 2
+       rtn, CS2 := amclcgo.MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_SECRET Error:", rtn)
+               return
+       }
+       fmt.Printf("Client Secret Share CS2: 0x")
+       amclcgo.MPIN_printBinary(CS2[:])
+
+       // Combine client secret shares
+       CS := make([]byte, amclcgo.G1S)
+       rtn, CS = amclcgo.MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_RECOMBINE_G1 Error:", rtn)
+               return
+       }
+       fmt.Printf("Client Secret CS: 0x")
+       amclcgo.MPIN_printBinary(CS[:])
+
+       // Generate time permit share 1
+       rtn, TP1 := amclcgo.MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_PERMIT Error:", rtn)
+               return
+       }
+       fmt.Printf("TP1: 0x")
+       amclcgo.MPIN_printBinary(TP1[:])
+
+       // Generate time permit share 2
+       rtn, TP2 := amclcgo.MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_PERMIT Error:", rtn)
+               return
+       }
+       fmt.Printf("TP2: 0x")
+       amclcgo.MPIN_printBinary(TP2[:])
+
+       // Combine time permit shares
+       rtn, TP := amclcgo.MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_RECOMBINE_G1(TP1, TP2) Error:", rtn)
+               return
+       }
+
+       // Client extracts PIN1 from secret to create Token
+       for PIN1 < 0 {
+               fmt.Printf("Please enter PIN to create token: ")
+               fmt.Scan(&PIN1)
+       }
+
+       rtn, TOKEN := amclcgo.MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
+       if rtn != 0 {
+               fmt.Printf("FAILURE: EXTRACT_PIN rtn: %d\n", rtn)
+               return
+       }
+       fmt.Printf("Client Token TK: 0x")
+       amclcgo.MPIN_printBinary(TOKEN[:])
+
+       //////   Client   //////
+
+       for PIN2 < 0 {
+               fmt.Printf("Please enter PIN to authenticate: ")
+               fmt.Scan(&PIN2)
+       }
+
+       ////// Client Pass 1 //////
+       // Send U and UT to server
+       var X [amclcgo.EGS]byte
+       fmt.Printf("X: 0x")
+       amclcgo.MPIN_printBinary(X[:])
+       rtn, XOut, SEC, U, UT := amclcgo.MPIN_CLIENT_1_WRAP(date, ID, rng, 
X[:], PIN2, TOKEN[:], TP[:])
+       if rtn != 0 {
+               fmt.Printf("FAILURE: CLIENT rtn: %d\n", rtn)
+               return
+       }
+       fmt.Printf("XOut: 0x")
+       amclcgo.MPIN_printBinary(XOut[:])
+
+       //////   Server Pass 1  //////
+       /* Calculate H(ID) and H(T|H(ID)) (if time permits enabled), and maps 
them to points on the curve HID and HTID resp. */
+       HID, HTID := amclcgo.MPIN_SERVER_1_WRAP(date, ID)
+
+       /* Send Y to Client */
+       rtn, Y := amclcgo.MPIN_RANDOM_GENERATE_WRAP(rng)
+       if rtn != 0 {
+               fmt.Println("MPIN_RANDOM_GENERATE Error:", rtn)
+               return
+       }
+       fmt.Printf("Y: 0x")
+       amclcgo.MPIN_printBinary(Y[:])
+
+       /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs 
-(x+y)*SEC */
+       rtn, V := amclcgo.MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
+       if rtn != 0 {
+               fmt.Printf("FAILURE: CLIENT_2 rtn: %d\n", rtn)
+       }
+
+       /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, 
xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+       /* If PIN error not required, set E and F = null */
+       rtn, _, _ = amclcgo.MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], 
SS[:], U[:], UT[:], V[:])
+       if rtn != 0 {
+               fmt.Printf("FAILURE: MPIN_SERVER_2 rtn: %d\n", rtn)
+       }
+       fmt.Printf("HID: 0x")
+       amclcgo.MPIN_printBinary(HID[:])
+       fmt.Printf("HTID: 0x")
+       amclcgo.MPIN_printBinary(HTID[:])
+
+       if rtn != 0 {
+               fmt.Printf("Authentication failed Error Code %d\n", rtn)
+               return
+       } else {
+               fmt.Printf("Authenticated ID: %s \n", IDstr)
+       }
+}
diff --git a/go/src/github.com/miracl/examples-go/mpinTwoPass.go 
b/go/src/github.com/miracl/examples-go/mpinTwoPass.go
index f86968e..f2c3d33 100644
--- a/go/src/github.com/miracl/examples-go/mpinTwoPass.go
+++ b/go/src/github.com/miracl/examples-go/mpinTwoPass.go
@@ -164,7 +164,7 @@ func main() {
                fmt.Scan(&PIN2)
        }
 
-       /* Cleints first pass. Calculate U and UT */
+       /* Clients first pass. Calculate U and UT */
        rtn = amcl.MPIN_CLIENT_1(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], 
U[:], UT[:], TP[:])
        if rtn != 0 {
                fmt.Printf("FAILURE: CLIENT rtn: %d\n", rtn)
diff --git a/go/src/github.com/miracl/examples-go/mpinTwoPass.go 
b/go/src/github.com/miracl/examples-go/mpinTwoPassWrap.go
similarity index 64%
copy from go/src/github.com/miracl/examples-go/mpinTwoPass.go
copy to go/src/github.com/miracl/examples-go/mpinTwoPassWrap.go
index f86968e..6ef787d 100644
--- a/go/src/github.com/miracl/examples-go/mpinTwoPass.go
+++ b/go/src/github.com/miracl/examples-go/mpinTwoPassWrap.go
@@ -58,34 +58,23 @@ func main() {
        const G2S = 4 * EFS   /* Group 2 Size */
        const EAS = amcl.MPIN_PAS
 
-       var MS1 [EGS]byte
-       var SS1 [G2S]byte
-       var CS1 [G1S]byte
-       var TP1 [G1S]byte
-       var MS2 [EGS]byte
-       var SS2 [G2S]byte
-       var CS2 [G1S]byte
-       var TP2 [G1S]byte
-       var SS [G2S]byte
-       var TP [G1S]byte
-       var TOKEN [G1S]byte
-       var SEC [G1S]byte
-       var U [G1S]byte
-       var UT [G1S]byte
        var X [EGS]byte
-       var Y [EGS]byte
-       var E [12 * EFS]byte
-       var F [12 * EFS]byte
-       var HID [G1S]byte
-       var HTID [G1S]byte
 
        // Generate Master Secret Share 1
-       amcl.MPIN_RANDOM_GENERATE(rng, MS1[:])
+       rtn, MS1 := amcl.MPIN_RANDOM_GENERATE_WRAP(rng)
+       if rtn != 0 {
+               fmt.Println("MPIN_RANDOM_GENERATE Error:", rtn)
+               return
+       }
        fmt.Printf("MS1: 0x")
        amcl.MPIN_printBinary(MS1[:])
 
        // Generate Master Secret Share 2
-       amcl.MPIN_RANDOM_GENERATE(rng, MS2[:])
+       rtn, MS2 := amcl.MPIN_RANDOM_GENERATE_WRAP(rng)
+       if rtn != 0 {
+               fmt.Println("MPIN_RANDOM_GENERATE Error:", rtn)
+               return
+       }
        fmt.Printf("MS2: 0x")
        amcl.MPIN_printBinary(MS2[:])
 
@@ -93,55 +82,81 @@ func main() {
        HCID := amcl.MPIN_HASH_ID(ID)
 
        // Generate server secret share 1
-       amcl.MPIN_GET_SERVER_SECRET(MS1[:], SS1[:])
+       rtn, SS1 := amcl.MPIN_GET_SERVER_SECRET_WRAP(MS1[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_SERVER_SECRET Error:", rtn)
+               return
+       }
        fmt.Printf("SS1: 0x")
        amcl.MPIN_printBinary(SS1[:])
 
        // Generate server secret share 2
-       amcl.MPIN_GET_SERVER_SECRET(MS2[:], SS2[:])
+       rtn, SS2 := amcl.MPIN_GET_SERVER_SECRET_WRAP(MS2[:])
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_SERVER_SECRET Error:", rtn)
+               return
+       }
        fmt.Printf("SS2: 0x")
        amcl.MPIN_printBinary(SS2[:])
 
        // Combine server secret shares
-       rtn := amcl.MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:])
+       rtn, SS := amcl.MPIN_RECOMBINE_G2_WRAP(SS1[:], SS2[:])
        if rtn != 0 {
-               fmt.Println("MPIN_RECOMBINE_G2(SS1, SS2, SS) Error:", rtn)
+               fmt.Println("MPIN_RECOMBINE_G2(SS1, SS2) Error:", rtn)
                return
        }
        fmt.Printf("SS: 0x")
        amcl.MPIN_printBinary(SS[:])
 
        // Generate client secret share 1
-       amcl.MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:])
+       rtn, CS1 := amcl.MPIN_GET_CLIENT_SECRET_WRAP(MS1[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_SECRET Error:", rtn)
+               return
+       }
        fmt.Printf("Client Secret CS: 0x")
        amcl.MPIN_printBinary(CS1[:])
 
        // Generate client secret share 2
-       amcl.MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:])
+       rtn, CS2 := amcl.MPIN_GET_CLIENT_SECRET_WRAP(MS2[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_SECRET Error:", rtn)
+               return
+       }
        fmt.Printf("Client Secret CS: 0x")
        amcl.MPIN_printBinary(CS2[:])
 
-       // Combine client secret shares : TOKEN is the full client secret
-       rtn = amcl.MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:])
+       // Combine client secret shares
+       rtn, CS := amcl.MPIN_RECOMBINE_G1_WRAP(CS1[:], CS2[:])
        if rtn != 0 {
-               fmt.Println("MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) Error:", rtn)
+               fmt.Println("MPIN_RECOMBINE_G1 Error:", rtn)
                return
        }
+       fmt.Printf("Client Secret CS: 0x")
+       amcl.MPIN_printBinary(CS[:])
 
        // Generate time permit share 1
-       amcl.MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:])
+       rtn, TP1 := amcl.MPIN_GET_CLIENT_PERMIT_WRAP(date, MS1[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_PERMIT Error:", rtn)
+               return
+       }
        fmt.Printf("TP1: 0x")
        amcl.MPIN_printBinary(TP1[:])
 
        // Generate time permit share 2
-       amcl.MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:])
+       rtn, TP2 := amcl.MPIN_GET_CLIENT_PERMIT_WRAP(date, MS2[:], HCID)
+       if rtn != 0 {
+               fmt.Println("MPIN_GET_CLIENT_PERMIT Error:", rtn)
+               return
+       }
        fmt.Printf("TP2: 0x")
        amcl.MPIN_printBinary(TP2[:])
 
        // Combine time permit shares
-       rtn = amcl.MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:])
+       rtn, TP := amcl.MPIN_RECOMBINE_G1_WRAP(TP1[:], TP2[:])
        if rtn != 0 {
-               fmt.Println("MPIN_RECOMBINE_G1(TP1, TP2, TP) Error:", rtn)
+               fmt.Println("MPIN_RECOMBINE_G1(TP1, TP2) Error:", rtn)
                return
        }
 
@@ -151,7 +166,7 @@ func main() {
                fmt.Scan(&PIN1)
        }
 
-       rtn = amcl.MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:])
+       rtn, TOKEN := amcl.MPIN_EXTRACT_PIN_WRAP(ID[:], PIN1, CS[:])
        if rtn != 0 {
                fmt.Printf("FAILURE: EXTRACT_PIN rtn: %d\n", rtn)
                return
@@ -164,28 +179,38 @@ func main() {
                fmt.Scan(&PIN2)
        }
 
-       /* Cleints first pass. Calculate U and UT */
-       rtn = amcl.MPIN_CLIENT_1(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], 
U[:], UT[:], TP[:])
+       /* Clients first pass. Calculate U and UT */
+       fmt.Printf("X: 0x")
+       amcl.MPIN_printBinary(X[:])
+       rtn, Xout, SEC, U, UT := amcl.MPIN_CLIENT_1_WRAP(date, ID, rng, X[:], 
PIN2, TOKEN[:], TP[:])
        if rtn != 0 {
                fmt.Printf("FAILURE: CLIENT rtn: %d\n", rtn)
                return
        }
+       fmt.Printf("Xout: 0x")
+       amcl.MPIN_printBinary(Xout[:])
 
        /* Server first pass. Calculate H(ID) and H(T|H(ID)) (if time permits 
enabled), and maps them to points on the curve HID and HTID resp. */
-       amcl.MPIN_SERVER_1(date, ID, HID[:], HTID[:])
+       HID, HTID := amcl.MPIN_SERVER_1_WRAP(date, ID)
 
        /* Server generates Random number Y and sends it to Client */
-       amcl.MPIN_RANDOM_GENERATE(rng, Y[:])
+       rtn, Y := amcl.MPIN_RANDOM_GENERATE_WRAP(rng)
+       if rtn != 0 {
+               fmt.Println("MPIN_RANDOM_GENERATE Error:", rtn)
+               return
+       }
+       fmt.Printf("Y: 0x")
+       amcl.MPIN_printBinary(Y[:])
 
        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs 
-(x+y)*SEC */
-       rtn = amcl.MPIN_CLIENT_2(X[:], Y[:], SEC[:])
+       rtn, V := amcl.MPIN_CLIENT_2_WRAP(X[:], Y[:], SEC[:])
        if rtn != 0 {
                fmt.Printf("FAILURE: CLIENT_2 rtn: %d\n", rtn)
        }
 
        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, 
xID and xCID and Server secret SST. E and F help kangaroos to find error. */
        /* If PIN error not required, set E and F = null */
-       rtn = amcl.MPIN_SERVER_2(date, HID[:], HTID[:], Y[:], SS[:], U[:], 
UT[:], SEC[:], E[:], F[:])
+       rtn, _, _ = amcl.MPIN_SERVER_2_WRAP(date, HID[:], HTID[:], Y[:], SS[:], 
U[:], UT[:], V[:])
        if rtn != 0 {
                fmt.Printf("FAILURE: MPIN_SERVER_2 rtn: %d\n", rtn)
        }
@@ -196,10 +221,6 @@ func main() {
 
        if rtn == amcl.MPIN_BAD_PIN {
                fmt.Printf("Authentication failed Error Code %d\n", rtn)
-               err := amcl.MPIN_KANGAROO(E[:], F[:])
-               if err != 0 {
-                       fmt.Printf("PIN Error %d\n", err)
-               }
                return
        } else {
                fmt.Printf("Authenticated ID: %s \n", IDstr)

Reply via email to