blob: 60ca3de4fabef770da098ba3c7b0d5373ded4bd0 [file] [log] [blame]
/*
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.
*/
/* test driver and function exerciser for MPIN API Functions */
package main
import "fmt"
func MPIN_printBinary(array []byte) {
for i:=0;i<len(array);i++ {
fmt.Printf("%02x", array[i])
}
fmt.Printf("\n")
}
func main() {
rng:=NewRAND()
var raw [100]byte
for i:=0;i<100;i++ {raw[i]=byte(i+1)}
rng.Seed(100,raw[:])
var sha=MPIN_HASH_TYPE
const EGS=MPIN_EGS
const EFS=MPIN_EFS
const G1S=2*EFS+1 /* Group 1 Size */
const G2S=4*EFS; /* Group 2 Size */
const EAS int=16
var S [EGS]byte
var SST [G2S]byte
var TOKEN [G1S]byte
var PERMIT [G1S]byte
var SEC [G1S]byte
var xID [G1S]byte
var xCID [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
var G1 [12*EFS]byte
var G2 [12*EFS]byte
var R [EGS]byte
var Z [G1S]byte
var W [EGS]byte
var T [G1S]byte
var CK [EAS]byte
var SK [EAS]byte
var HSID []byte
/* Trusted Authority set-up */
MPIN_RANDOM_GENERATE(rng,S[:])
fmt.Printf("Master Secret s: 0x"); MPIN_printBinary(S[:])
/* Create Client Identity */
IDstr:= "testUser@miracl.com"
CLIENT_ID:=[]byte(IDstr)
HCID:=MPIN_HASH_ID(sha,CLIENT_ID) /* Either Client or TA calculates Hash(ID) - you decide! */
fmt.Printf("Client ID= "); MPIN_printBinary(CLIENT_ID)
fmt.Printf("\n")
/* Client and Server are issued secrets by DTA */
MPIN_GET_SERVER_SECRET(S[:],SST[:])
fmt.Printf("Server Secret SS: 0x"); MPIN_printBinary(SST[:])
MPIN_GET_CLIENT_SECRET(S[:],HCID,TOKEN[:])
fmt.Printf("Client Secret CS: 0x");
MPIN_printBinary(TOKEN[:])
/* Client extracts PIN from secret to create Token */
pin:=1234
fmt.Printf("Client extracts PIN= %d",pin)
fmt.Printf("\n")
rtn:=MPIN_EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN[:])
if rtn != 0 {
fmt.Printf("FAILURE: EXTRACT_PIN rtn: %d",rtn);
fmt.Printf("\n")
}
fmt.Printf("Client Token TK: 0x")
MPIN_printBinary(TOKEN[:]);
if FULL {
MPIN_PRECOMPUTE(TOKEN[:],HCID,G1[:],G2[:])
}
date:=0
if PERMITS {
date=MPIN_today()
/* Client gets "Time Token" permit from DTA */
MPIN_GET_CLIENT_PERMIT(sha,date,S[:],HCID,PERMIT[:])
fmt.Printf("Time Permit TP: 0x"); MPIN_printBinary(PERMIT[:])
/* This encoding makes Time permit look random - Elligator squared */
MPIN_ENCODING(rng,PERMIT[:])
fmt.Printf("Encoded Time Permit TP: 0x"); MPIN_printBinary(PERMIT[:])
MPIN_DECODING(PERMIT[:])
fmt.Printf("Decoded Time Permit TP: 0x"); MPIN_printBinary(PERMIT[:])
}
pin=0
fmt.Printf("\nPIN= ")
fmt.Scanf("%d",&pin)
pxID:=xID[:]
pxCID:=xCID[:]
pHID:=HID[:]
pHTID:=HTID[:]
pE:=E[:]
pF:=F[:]
pPERMIT:=PERMIT[:]
var prHID []byte
if date!=0 {
prHID=pHTID;
if !PINERROR {
pxID=nil
// pHID=nil
}
} else {
prHID=pHID
pPERMIT=nil
pxCID=nil
pHTID=nil
}
if !PINERROR {
pE=nil
pF=nil
}
if SINGLE_PASS {
fmt.Printf("MPIN Single Pass\n")
timeValue:= MPIN_GET_TIME()
rtn=MPIN_CLIENT(sha,date,CLIENT_ID,rng,X[:],pin,TOKEN[:],SEC[:],pxID,pxCID,pPERMIT,timeValue,Y[:])
if rtn != 0 {
fmt.Printf("FAILURE: CLIENT rtn: %d\n",rtn)
}
if FULL {
HCID=MPIN_HASH_ID(sha,CLIENT_ID)
MPIN_GET_G1_MULTIPLE(rng,1,R[:],HCID,Z[:]) /* Also Send Z=r.ID to Server, remember random r */
}
rtn=MPIN_SERVER(sha,date,pHID,pHTID,Y[:],SST[:],pxID,pxCID,SEC[:],pE,pF,CLIENT_ID,timeValue)
if rtn != 0 {
fmt.Printf("FAILURE: SERVER rtn: %d\n",rtn)
}
if FULL {
HSID=MPIN_HASH_ID(sha,CLIENT_ID);
MPIN_GET_G1_MULTIPLE(rng,0,W[:],prHID,T[:]); /* Also send T=w.ID to client, remember random w */
}
} else {
fmt.Printf("MPIN Multi Pass\n")
/* Send U=x.ID to server, and recreate secret from token and pin */
rtn=MPIN_CLIENT_1(sha,date,CLIENT_ID,rng,X[:],pin,TOKEN[:],SEC[:],pxID,pxCID,pPERMIT);
if rtn != 0 {
fmt.Printf("FAILURE: CLIENT_1 rtn: %d\n",rtn)
}
if FULL {
HCID=MPIN_HASH_ID(sha,CLIENT_ID)
MPIN_GET_G1_MULTIPLE(rng,1,R[:],HCID,Z[:]) /* Also Send Z=r.ID to Server, remember random r */
}
/* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
MPIN_SERVER_1(sha,date,CLIENT_ID,pHID,pHTID)
/* Server generates Random number Y and sends it to Client */
MPIN_RANDOM_GENERATE(rng,Y[:]);
if FULL {
HSID=MPIN_HASH_ID(sha,CLIENT_ID);
MPIN_GET_G1_MULTIPLE(rng,0,W[:],prHID,T[:]) /* Also send T=w.ID to client, remember random w */
}
/* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
rtn=MPIN_CLIENT_2(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=MPIN_SERVER_2(date,pHID,pHTID,Y[:],SST[:],pxID,pxCID,SEC[:],pE,pF)
if rtn!=0 {
fmt.Printf("FAILURE: SERVER_1 rtn: %d\n",rtn)
}
if rtn == MPIN_BAD_PIN {
fmt.Printf("Server says - Bad Pin. I don't know you. Feck off.\n")
if PINERROR {
err:=MPIN_KANGAROO(E[:],F[:])
if err!=0 {fmt.Printf("(Client PIN is out by %d)\n",err)}
}
return
} else {
fmt.Printf("Server says - PIN is good! You really are "+IDstr)
fmt.Printf("\n")
}
if FULL {
H:=MPIN_HASH_ALL(sha,HCID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]);
MPIN_CLIENT_KEY(sha,G1[:],G2[:],pin,R[:],X[:],H[:],T[:],CK[:])
fmt.Printf("Client Key = 0x"); MPIN_printBinary(CK[:])
H=MPIN_HASH_ALL(sha,HSID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]);
MPIN_SERVER_KEY(sha,Z[:],SST[:],W[:],H[:],pHID,pxID,pxCID,SK[:])
fmt.Printf("Server Key = 0x"); MPIN_printBinary(SK[:])
}
}
}