| /* |
| 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 ECDH/ECIES/ECDSA API Functions */ |
| |
| |
| package main |
| |
| import "fmt" |
| |
| import "github.com/milagro-crypto/amcl/version3/go/amcl" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/ED25519" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/NIST256" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/GOLDILOCKS" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/BN254" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS383" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS24" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS48" |
| import "github.com/milagro-crypto/amcl/version3/go/amcl/RSA2048" |
| |
| |
| //import "amcl" |
| //import "amcl/ED25519" |
| //import "amcl/BN254" |
| //import "amcl/RSA2048" |
| |
| |
| func printBinary(array []byte) { |
| for i:=0;i<len(array);i++ { |
| fmt.Printf("%02x", array[i]) |
| } |
| fmt.Printf("\n") |
| } |
| |
| |
| func ecdh_ED25519(rng *amcl.RAND) { |
| // j:=0 |
| pp:="M0ng00se" |
| res:=0 |
| |
| var sha=ED25519.HASH_TYPE |
| |
| var S1 [ED25519.EGS]byte |
| var W0 [2*ED25519.EFS+1]byte |
| var W1 [2*ED25519.EFS+1]byte |
| var Z0 [ED25519.EFS]byte |
| var Z1 [ED25519.EFS]byte |
| var SALT [8]byte |
| var P1 [3]byte |
| var P2 [4]byte |
| var V [2*ED25519.EFS+1]byte |
| var M [17]byte |
| var T [12]byte |
| var CS [ED25519.EGS]byte |
| var DS [ED25519.EGS]byte |
| |
| for i:=0;i<8;i++ {SALT[i]=byte(i+1)} // set Salt |
| |
| fmt.Printf("\nTesting ECDH/ECDSA/ECIES\n") |
| fmt.Printf("Alice's Passphrase= "+pp) |
| fmt.Printf("\n"); |
| PW:=[]byte(pp) |
| |
| /* private key S0 of size MGS bytes derived from Password and Salt */ |
| |
| S0:=ED25519.ECDH_PBKDF2(sha,PW,SALT[:],1000,ED25519.EGS) |
| |
| fmt.Printf("Alice's private key= 0x") |
| printBinary(S0) |
| |
| /* Generate Key pair S/W */ |
| ED25519.ECDH_KEY_PAIR_GENERATE(nil,S0,W0[:]) |
| |
| fmt.Printf("Alice's public key= 0x") |
| printBinary(W0[:]); |
| |
| res=ED25519.ECDH_PUBLIC_KEY_VALIDATE(W0[:]) |
| if res!=0 { |
| fmt.Printf("ECP Public Key is invalid!\n") |
| return |
| } |
| |
| /* Random private key for other party */ |
| ED25519.ECDH_KEY_PAIR_GENERATE(rng,S1[:],W1[:]) |
| |
| fmt.Printf("Servers private key= 0x"); |
| printBinary(S1[:]) |
| |
| fmt.Printf("Servers public key= 0x") |
| printBinary(W1[:]) |
| |
| |
| res=ED25519.ECDH_PUBLIC_KEY_VALIDATE(W1[:]) |
| if res!=0 { |
| fmt.Printf("ECP Public Key is invalid!\n") |
| return |
| } |
| /* Calculate common key using DH - IEEE 1363 method */ |
| |
| ED25519.ECDH_ECPSVDP_DH(S0,W1[:],Z0[:]) |
| ED25519.ECDH_ECPSVDP_DH(S1[:],W0[:],Z1[:]) |
| |
| same:=true |
| for i:=0;i<ED25519.EFS;i++ { |
| if Z0[i]!=Z1[i] {same=false} |
| } |
| |
| if !same { |
| fmt.Printf("*** ECPSVDP-DH Failed\n"); |
| return |
| } |
| |
| KEY:=ED25519.ECDH_KDF2(sha,Z0[:],nil,ED25519.AESKEY); |
| |
| fmt.Printf("Alice's DH Key= 0x"); printBinary(KEY) |
| fmt.Printf("Servers DH Key= 0x"); printBinary(KEY) |
| |
| if ED25519.CURVETYPE!=ED25519.MONTGOMERY { |
| fmt.Printf("Testing ECIES\n"); |
| |
| P1[0]=0x0; P1[1]=0x1; P1[2]=0x2 |
| P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3 |
| |
| for i:=0;i<=16;i++ {M[i]=byte(i)} |
| |
| C:=ED25519.ECDH_ECIES_ENCRYPT(sha,P1[:],P2[:],rng,W1[:],M[:],V[:],T[:]) |
| |
| fmt.Printf("Ciphertext= \n") |
| fmt.Printf("V= 0x"); printBinary(V[:]) |
| fmt.Printf("C= 0x"); printBinary(C) |
| fmt.Printf("T= 0x"); printBinary(T[:]) |
| |
| |
| RM:=ED25519.ECDH_ECIES_DECRYPT(sha,P1[:],P2[:],V[:],C,T[:],S1[:]) |
| if RM==nil { |
| fmt.Printf("*** ECIES Decryption Failed\n") |
| return |
| } else {fmt.Printf("Decryption succeeded\n")} |
| |
| fmt.Printf("Message is 0x"); printBinary(RM) |
| |
| fmt.Printf("Testing ECDSA\n"); |
| |
| if ED25519.ECDH_ECPSP_DSA(sha,rng,S0,M[:],CS[:],DS[:])!=0 { |
| fmt.Printf("***ECDSA Signature Failed\n") |
| return |
| } |
| fmt.Printf("Signature= \n") |
| fmt.Printf("C= 0x"); printBinary(CS[:]) |
| fmt.Printf("D= 0x"); printBinary(DS[:]) |
| |
| if ED25519.ECDH_ECPVP_DSA(sha,W0[:],M[:],CS[:],DS[:])!=0 { |
| fmt.Printf("***ECDSA Verification Failed\n") |
| return |
| } else {fmt.Printf("ECDSA Signature/Verification succeeded \n")} |
| } |
| } |
| |
| |
| func ecdh_NIST256(rng *amcl.RAND) { |
| // j:=0 |
| pp:="M0ng00se" |
| res:=0 |
| |
| var sha=NIST256.HASH_TYPE |
| |
| var S1 [NIST256.EGS]byte |
| var W0 [2*NIST256.EFS+1]byte |
| var W1 [2*NIST256.EFS+1]byte |
| var Z0 [NIST256.EFS]byte |
| var Z1 [NIST256.EFS]byte |
| var SALT [8]byte |
| var P1 [3]byte |
| var P2 [4]byte |
| var V [2*NIST256.EFS+1]byte |
| var M [17]byte |
| var T [12]byte |
| var CS [NIST256.EGS]byte |
| var DS [NIST256.EGS]byte |
| |
| for i:=0;i<8;i++ {SALT[i]=byte(i+1)} // set Salt |
| |
| fmt.Printf("\nTesting ECDH/ECDSA/ECIES\n") |
| fmt.Printf("Alice's Passphrase= "+pp) |
| fmt.Printf("\n"); |
| PW:=[]byte(pp) |
| |
| /* private key S0 of size MGS bytes derived from Password and Salt */ |
| |
| S0:=NIST256.ECDH_PBKDF2(sha,PW,SALT[:],1000,NIST256.EGS) |
| |
| fmt.Printf("Alice's private key= 0x") |
| printBinary(S0) |
| |
| /* Generate Key pair S/W */ |
| NIST256.ECDH_KEY_PAIR_GENERATE(nil,S0,W0[:]) |
| |
| fmt.Printf("Alice's public key= 0x") |
| printBinary(W0[:]); |
| |
| res=NIST256.ECDH_PUBLIC_KEY_VALIDATE(W0[:]) |
| if res!=0 { |
| fmt.Printf("ECP Public Key is invalid!\n") |
| return |
| } |
| |
| /* Random private key for other party */ |
| NIST256.ECDH_KEY_PAIR_GENERATE(rng,S1[:],W1[:]) |
| |
| fmt.Printf("Servers private key= 0x"); |
| printBinary(S1[:]) |
| |
| fmt.Printf("Servers public key= 0x") |
| printBinary(W1[:]) |
| |
| |
| res=NIST256.ECDH_PUBLIC_KEY_VALIDATE(W1[:]) |
| if res!=0 { |
| fmt.Printf("ECP Public Key is invalid!\n") |
| return |
| } |
| /* Calculate common key using DH - IEEE 1363 method */ |
| |
| NIST256.ECDH_ECPSVDP_DH(S0,W1[:],Z0[:]) |
| NIST256.ECDH_ECPSVDP_DH(S1[:],W0[:],Z1[:]) |
| |
| same:=true |
| for i:=0;i<NIST256.EFS;i++ { |
| if Z0[i]!=Z1[i] {same=false} |
| } |
| |
| if !same { |
| fmt.Printf("*** ECPSVDP-DH Failed\n"); |
| return |
| } |
| |
| KEY:=NIST256.ECDH_KDF2(sha,Z0[:],nil,NIST256.AESKEY); |
| |
| fmt.Printf("Alice's DH Key= 0x"); printBinary(KEY) |
| fmt.Printf("Servers DH Key= 0x"); printBinary(KEY) |
| |
| if NIST256.CURVETYPE!=NIST256.MONTGOMERY { |
| fmt.Printf("Testing ECIES\n"); |
| |
| P1[0]=0x0; P1[1]=0x1; P1[2]=0x2 |
| P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3 |
| |
| for i:=0;i<=16;i++ {M[i]=byte(i)} |
| |
| C:=NIST256.ECDH_ECIES_ENCRYPT(sha,P1[:],P2[:],rng,W1[:],M[:],V[:],T[:]) |
| |
| fmt.Printf("Ciphertext= \n") |
| fmt.Printf("V= 0x"); printBinary(V[:]) |
| fmt.Printf("C= 0x"); printBinary(C) |
| fmt.Printf("T= 0x"); printBinary(T[:]) |
| |
| |
| RM:=NIST256.ECDH_ECIES_DECRYPT(sha,P1[:],P2[:],V[:],C,T[:],S1[:]) |
| if RM==nil { |
| fmt.Printf("*** ECIES Decryption Failed\n") |
| return |
| } else {fmt.Printf("Decryption succeeded\n")} |
| |
| fmt.Printf("Message is 0x"); printBinary(RM) |
| |
| fmt.Printf("Testing ECDSA\n"); |
| |
| if NIST256.ECDH_ECPSP_DSA(sha,rng,S0,M[:],CS[:],DS[:])!=0 { |
| fmt.Printf("***ECDSA Signature Failed\n") |
| return |
| } |
| fmt.Printf("Signature= \n") |
| fmt.Printf("C= 0x"); printBinary(CS[:]) |
| fmt.Printf("D= 0x"); printBinary(DS[:]) |
| |
| if NIST256.ECDH_ECPVP_DSA(sha,W0[:],M[:],CS[:],DS[:])!=0 { |
| fmt.Printf("***ECDSA Verification Failed\n") |
| return |
| } else {fmt.Printf("ECDSA Signature/Verification succeeded \n")} |
| } |
| } |
| |
| |
| func ecdh_GOLDILOCKS(rng *amcl.RAND) { |
| // j:=0 |
| pp:="M0ng00se" |
| res:=0 |
| |
| var sha=GOLDILOCKS.HASH_TYPE |
| |
| var S1 [GOLDILOCKS.EGS]byte |
| var W0 [2*GOLDILOCKS.EFS+1]byte |
| var W1 [2*GOLDILOCKS.EFS+1]byte |
| var Z0 [GOLDILOCKS.EFS]byte |
| var Z1 [GOLDILOCKS.EFS]byte |
| var SALT [8]byte |
| var P1 [3]byte |
| var P2 [4]byte |
| var V [2*GOLDILOCKS.EFS+1]byte |
| var M [17]byte |
| var T [12]byte |
| var CS [GOLDILOCKS.EGS]byte |
| var DS [GOLDILOCKS.EGS]byte |
| |
| for i:=0;i<8;i++ {SALT[i]=byte(i+1)} // set Salt |
| |
| fmt.Printf("\nTesting ECDH/ECDSA/ECIES\n") |
| fmt.Printf("Alice's Passphrase= "+pp) |
| fmt.Printf("\n"); |
| PW:=[]byte(pp) |
| |
| /* private key S0 of size MGS bytes derived from Password and Salt */ |
| |
| S0:=GOLDILOCKS.ECDH_PBKDF2(sha,PW,SALT[:],1000,GOLDILOCKS.EGS) |
| |
| fmt.Printf("Alice's private key= 0x") |
| printBinary(S0) |
| |
| /* Generate Key pair S/W */ |
| GOLDILOCKS.ECDH_KEY_PAIR_GENERATE(nil,S0,W0[:]) |
| |
| fmt.Printf("Alice's public key= 0x") |
| printBinary(W0[:]); |
| |
| res=GOLDILOCKS.ECDH_PUBLIC_KEY_VALIDATE(W0[:]) |
| if res!=0 { |
| fmt.Printf("ECP Public Key is invalid!\n") |
| return |
| } |
| |
| /* Random private key for other party */ |
| GOLDILOCKS.ECDH_KEY_PAIR_GENERATE(rng,S1[:],W1[:]) |
| |
| fmt.Printf("Servers private key= 0x"); |
| printBinary(S1[:]) |
| |
| fmt.Printf("Servers public key= 0x") |
| printBinary(W1[:]) |
| |
| |
| res=GOLDILOCKS.ECDH_PUBLIC_KEY_VALIDATE(W1[:]) |
| if res!=0 { |
| fmt.Printf("ECP Public Key is invalid!\n") |
| return |
| } |
| /* Calculate common key using DH - IEEE 1363 method */ |
| |
| GOLDILOCKS.ECDH_ECPSVDP_DH(S0,W1[:],Z0[:]) |
| GOLDILOCKS.ECDH_ECPSVDP_DH(S1[:],W0[:],Z1[:]) |
| |
| same:=true |
| for i:=0;i<GOLDILOCKS.EFS;i++ { |
| if Z0[i]!=Z1[i] {same=false} |
| } |
| |
| if !same { |
| fmt.Printf("*** ECPSVDP-DH Failed\n"); |
| return |
| } |
| |
| KEY:=GOLDILOCKS.ECDH_KDF2(sha,Z0[:],nil,GOLDILOCKS.AESKEY); |
| |
| fmt.Printf("Alice's DH Key= 0x"); printBinary(KEY) |
| fmt.Printf("Servers DH Key= 0x"); printBinary(KEY) |
| |
| if GOLDILOCKS.CURVETYPE!=GOLDILOCKS.MONTGOMERY { |
| fmt.Printf("Testing ECIES\n"); |
| |
| P1[0]=0x0; P1[1]=0x1; P1[2]=0x2 |
| P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3 |
| |
| for i:=0;i<=16;i++ {M[i]=byte(i)} |
| |
| C:=GOLDILOCKS.ECDH_ECIES_ENCRYPT(sha,P1[:],P2[:],rng,W1[:],M[:],V[:],T[:]) |
| |
| fmt.Printf("Ciphertext= \n") |
| fmt.Printf("V= 0x"); printBinary(V[:]) |
| fmt.Printf("C= 0x"); printBinary(C) |
| fmt.Printf("T= 0x"); printBinary(T[:]) |
| |
| |
| RM:=GOLDILOCKS.ECDH_ECIES_DECRYPT(sha,P1[:],P2[:],V[:],C,T[:],S1[:]) |
| if RM==nil { |
| fmt.Printf("*** ECIES Decryption Failed\n") |
| return |
| } else {fmt.Printf("Decryption succeeded\n")} |
| |
| fmt.Printf("Message is 0x"); printBinary(RM) |
| |
| fmt.Printf("Testing ECDSA\n"); |
| |
| if GOLDILOCKS.ECDH_ECPSP_DSA(sha,rng,S0,M[:],CS[:],DS[:])!=0 { |
| fmt.Printf("***ECDSA Signature Failed\n") |
| return |
| } |
| fmt.Printf("Signature= \n") |
| fmt.Printf("C= 0x"); printBinary(CS[:]) |
| fmt.Printf("D= 0x"); printBinary(DS[:]) |
| |
| if GOLDILOCKS.ECDH_ECPVP_DSA(sha,W0[:],M[:],CS[:],DS[:])!=0 { |
| fmt.Printf("***ECDSA Verification Failed\n") |
| return |
| } else {fmt.Printf("ECDSA Signature/Verification succeeded \n")} |
| } |
| } |
| |
| |
| /* Configure mode of operation */ |
| |
| const PERMITS bool=true |
| const PINERROR bool=true |
| const FULL bool=true |
| const SINGLE_PASS bool=false |
| |
| |
| func mpin_BN254(rng *amcl.RAND) { |
| |
| var sha=BN254.HASH_TYPE |
| |
| const MGS=BN254.MGS |
| const MFS=BN254.MFS |
| const G1S=2*MFS+1 /* Group 1 Size */ |
| const G2S=4*MFS; /* Group 2 Size */ |
| |
| var S [MGS]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 [MGS]byte |
| var Y [MGS]byte |
| var E [12*MFS]byte |
| var F [12*MFS]byte |
| var HID [G1S]byte |
| var HTID [G1S]byte |
| |
| var G1 [12*MFS]byte |
| var G2 [12*MFS]byte |
| var R [MGS]byte |
| var Z [G1S]byte |
| var W [MGS]byte |
| var T [G1S]byte |
| var CK [BN254.AESKEY]byte |
| var SK [BN254.AESKEY]byte |
| |
| var HSID []byte |
| |
| |
| /* Trusted Authority set-up */ |
| |
| fmt.Printf("\nTesting MPIN\n") |
| BN254.MPIN_RANDOM_GENERATE(rng,S[:]) |
| fmt.Printf("Master Secret s: 0x"); printBinary(S[:]) |
| |
| /* Create Client Identity */ |
| IDstr:= "testUser@miracl.com" |
| CLIENT_ID:=[]byte(IDstr) |
| |
| HCID:=BN254.MPIN_HASH_ID(sha,CLIENT_ID) /* Either Client or TA calculates Hash(ID) - you decide! */ |
| |
| fmt.Printf("Client ID= "); printBinary(CLIENT_ID) |
| fmt.Printf("\n") |
| |
| /* Client and Server are issued secrets by DTA */ |
| BN254.MPIN_GET_SERVER_SECRET(S[:],SST[:]) |
| fmt.Printf("Server Secret SS: 0x"); printBinary(SST[:]) |
| |
| BN254.MPIN_GET_CLIENT_SECRET(S[:],HCID,TOKEN[:]) |
| fmt.Printf("Client Secret CS: 0x"); |
| printBinary(TOKEN[:]) |
| |
| /* Client extracts PIN from secret to create Token */ |
| pin:=1234 |
| fmt.Printf("Client extracts PIN= %d",pin) |
| fmt.Printf("\n") |
| rtn:=BN254.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") |
| printBinary(TOKEN[:]); |
| |
| if FULL { |
| BN254.MPIN_PRECOMPUTE(TOKEN[:],HCID,G1[:],G2[:]) |
| } |
| |
| date:=0 |
| if PERMITS { |
| date=BN254.Today() |
| /* Client gets "Time Token" permit from DTA */ |
| BN254.MPIN_GET_CLIENT_PERMIT(sha,date,S[:],HCID,PERMIT[:]) |
| fmt.Printf("Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| |
| /* This encoding makes Time permit look random - Elligator squared */ |
| BN254.MPIN_ENCODING(rng,PERMIT[:]) |
| fmt.Printf("Encoded Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| BN254.MPIN_DECODING(PERMIT[:]) |
| fmt.Printf("Decoded Time Permit TP: 0x"); 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:= BN254.MPIN_GET_TIME() |
| rtn=BN254.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=BN254.MPIN_HASH_ID(sha,CLIENT_ID) |
| BN254.MPIN_GET_G1_MULTIPLE(rng,1,R[:],HCID,Z[:]) /* Also Send Z=r.ID to Server, remember random r */ |
| } |
| |
| rtn=BN254.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=BN254.MPIN_HASH_ID(sha,CLIENT_ID); |
| BN254.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=BN254.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=BN254.MPIN_HASH_ID(sha,CLIENT_ID) |
| BN254.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. */ |
| BN254.MPIN_SERVER_1(sha,date,CLIENT_ID,pHID,pHTID) |
| |
| /* Server generates Random number Y and sends it to Client */ |
| BN254.MPIN_RANDOM_GENERATE(rng,Y[:]); |
| |
| if FULL { |
| HSID=BN254.MPIN_HASH_ID(sha,CLIENT_ID); |
| BN254.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=BN254.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=BN254.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 == BN254.BAD_PIN { |
| fmt.Printf("Server says - Bad Pin. I don't know you. Feck off.\n") |
| if PINERROR { |
| err:=BN254.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:=BN254.MPIN_HASH_ALL(sha,HCID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BN254.MPIN_CLIENT_KEY(sha,G1[:],G2[:],pin,R[:],X[:],H[:],T[:],CK[:]) |
| fmt.Printf("Client Key = 0x"); printBinary(CK[:]) |
| |
| H=BN254.MPIN_HASH_ALL(sha,HSID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BN254.MPIN_SERVER_KEY(sha,Z[:],SST[:],W[:],H[:],pHID,pxID,pxCID,SK[:]) |
| fmt.Printf("Server Key = 0x"); printBinary(SK[:]) |
| } |
| } |
| } |
| |
| |
| func mpin_BLS383(rng *amcl.RAND) { |
| |
| var sha=BLS383.HASH_TYPE |
| |
| const MGS=BLS383.MGS |
| const MFS=BLS383.MFS |
| const G1S=2*MFS+1 /* Group 1 Size */ |
| const G2S=4*MFS; /* Group 2 Size */ |
| |
| var S [MGS]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 [MGS]byte |
| var Y [MGS]byte |
| var E [12*MFS]byte |
| var F [12*MFS]byte |
| var HID [G1S]byte |
| var HTID [G1S]byte |
| |
| var G1 [12*MFS]byte |
| var G2 [12*MFS]byte |
| var R [MGS]byte |
| var Z [G1S]byte |
| var W [MGS]byte |
| var T [G1S]byte |
| var CK [BLS383.AESKEY]byte |
| var SK [BLS383.AESKEY]byte |
| |
| var HSID []byte |
| |
| |
| /* Trusted Authority set-up */ |
| |
| fmt.Printf("\nTesting MPIN\n") |
| BLS383.MPIN_RANDOM_GENERATE(rng,S[:]) |
| fmt.Printf("Master Secret s: 0x"); printBinary(S[:]) |
| |
| /* Create Client Identity */ |
| IDstr:= "testUser@miracl.com" |
| CLIENT_ID:=[]byte(IDstr) |
| |
| HCID:=BLS383.MPIN_HASH_ID(sha,CLIENT_ID) /* Either Client or TA calculates Hash(ID) - you decide! */ |
| |
| fmt.Printf("Client ID= "); printBinary(CLIENT_ID) |
| fmt.Printf("\n") |
| |
| /* Client and Server are issued secrets by DTA */ |
| BLS383.MPIN_GET_SERVER_SECRET(S[:],SST[:]) |
| fmt.Printf("Server Secret SS: 0x"); printBinary(SST[:]) |
| |
| BLS383.MPIN_GET_CLIENT_SECRET(S[:],HCID,TOKEN[:]) |
| fmt.Printf("Client Secret CS: 0x"); |
| printBinary(TOKEN[:]) |
| |
| /* Client extracts PIN from secret to create Token */ |
| pin:=1234 |
| fmt.Printf("Client extracts PIN= %d",pin) |
| fmt.Printf("\n") |
| rtn:=BLS383.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") |
| printBinary(TOKEN[:]); |
| |
| if FULL { |
| BLS383.MPIN_PRECOMPUTE(TOKEN[:],HCID,G1[:],G2[:]) |
| } |
| |
| date:=0 |
| if PERMITS { |
| date=BLS383.Today() |
| /* Client gets "Time Token" permit from DTA */ |
| BLS383.MPIN_GET_CLIENT_PERMIT(sha,date,S[:],HCID,PERMIT[:]) |
| fmt.Printf("Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| |
| /* This encoding makes Time permit look random - Elligator squared */ |
| BLS383.MPIN_ENCODING(rng,PERMIT[:]) |
| fmt.Printf("Encoded Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| BLS383.MPIN_DECODING(PERMIT[:]) |
| fmt.Printf("Decoded Time Permit TP: 0x"); 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:= BLS383.MPIN_GET_TIME() |
| rtn=BLS383.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=BLS383.MPIN_HASH_ID(sha,CLIENT_ID) |
| BLS383.MPIN_GET_G1_MULTIPLE(rng,1,R[:],HCID,Z[:]) /* Also Send Z=r.ID to Server, remember random r */ |
| } |
| |
| rtn=BLS383.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=BLS383.MPIN_HASH_ID(sha,CLIENT_ID); |
| BLS383.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=BLS383.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=BLS383.MPIN_HASH_ID(sha,CLIENT_ID) |
| BLS383.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. */ |
| BLS383.MPIN_SERVER_1(sha,date,CLIENT_ID,pHID,pHTID) |
| |
| /* Server generates Random number Y and sends it to Client */ |
| BLS383.MPIN_RANDOM_GENERATE(rng,Y[:]); |
| |
| if FULL { |
| HSID=BLS383.MPIN_HASH_ID(sha,CLIENT_ID); |
| BLS383.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=BLS383.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=BLS383.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 == BLS383.BAD_PIN { |
| fmt.Printf("Server says - Bad Pin. I don't know you. Feck off.\n") |
| if PINERROR { |
| err:=BLS383.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:=BLS383.MPIN_HASH_ALL(sha,HCID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BLS383.MPIN_CLIENT_KEY(sha,G1[:],G2[:],pin,R[:],X[:],H[:],T[:],CK[:]) |
| fmt.Printf("Client Key = 0x"); printBinary(CK[:]) |
| |
| H=BLS383.MPIN_HASH_ALL(sha,HSID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BLS383.MPIN_SERVER_KEY(sha,Z[:],SST[:],W[:],H[:],pHID,pxID,pxCID,SK[:]) |
| fmt.Printf("Server Key = 0x"); printBinary(SK[:]) |
| } |
| } |
| } |
| |
| |
| func mpin_BLS24(rng *amcl.RAND) { |
| |
| var sha=BLS24.HASH_TYPE |
| |
| const MGS=BLS24.MGS |
| const MFS=BLS24.MFS |
| const G1S=2*MFS+1 /* Group 1 Size */ |
| const G2S=8*MFS; /* Group 2 Size */ |
| |
| var S [MGS]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 [MGS]byte |
| var Y [MGS]byte |
| var E [24*MFS]byte |
| var F [24*MFS]byte |
| var HID [G1S]byte |
| var HTID [G1S]byte |
| |
| var G1 [24*MFS]byte |
| var G2 [24*MFS]byte |
| var R [MGS]byte |
| var Z [G1S]byte |
| var W [MGS]byte |
| var T [G1S]byte |
| var CK [BLS24.AESKEY]byte |
| var SK [BLS24.AESKEY]byte |
| |
| var HSID []byte |
| |
| |
| /* Trusted Authority set-up */ |
| |
| fmt.Printf("\nTesting MPIN\n") |
| BLS24.MPIN_RANDOM_GENERATE(rng,S[:]) |
| fmt.Printf("Master Secret s: 0x"); printBinary(S[:]) |
| |
| /* Create Client Identity */ |
| IDstr:= "testUser@miracl.com" |
| CLIENT_ID:=[]byte(IDstr) |
| |
| HCID:=BLS24.MPIN_HASH_ID(sha,CLIENT_ID) /* Either Client or TA calculates Hash(ID) - you decide! */ |
| |
| fmt.Printf("Client ID= "); printBinary(CLIENT_ID) |
| fmt.Printf("\n") |
| |
| /* Client and Server are issued secrets by DTA */ |
| BLS24.MPIN_GET_SERVER_SECRET(S[:],SST[:]) |
| fmt.Printf("Server Secret SS: 0x"); printBinary(SST[:]) |
| |
| BLS24.MPIN_GET_CLIENT_SECRET(S[:],HCID,TOKEN[:]) |
| fmt.Printf("Client Secret CS: 0x"); |
| printBinary(TOKEN[:]) |
| |
| /* Client extracts PIN from secret to create Token */ |
| pin:=1234 |
| fmt.Printf("Client extracts PIN= %d",pin) |
| fmt.Printf("\n") |
| rtn:=BLS24.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") |
| printBinary(TOKEN[:]); |
| |
| if FULL { |
| BLS24.MPIN_PRECOMPUTE(TOKEN[:],HCID,G1[:],G2[:]) |
| } |
| |
| date:=0 |
| if PERMITS { |
| date=BLS24.Today() |
| /* Client gets "Time Token" permit from DTA */ |
| BLS24.MPIN_GET_CLIENT_PERMIT(sha,date,S[:],HCID,PERMIT[:]) |
| fmt.Printf("Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| |
| /* This encoding makes Time permit look random - Elligator squared */ |
| BLS24.MPIN_ENCODING(rng,PERMIT[:]) |
| fmt.Printf("Encoded Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| BLS24.MPIN_DECODING(PERMIT[:]) |
| fmt.Printf("Decoded Time Permit TP: 0x"); 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:= BLS24.MPIN_GET_TIME() |
| rtn=BLS24.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=BLS24.MPIN_HASH_ID(sha,CLIENT_ID) |
| BLS24.MPIN_GET_G1_MULTIPLE(rng,1,R[:],HCID,Z[:]) /* Also Send Z=r.ID to Server, remember random r */ |
| } |
| |
| rtn=BLS24.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=BLS24.MPIN_HASH_ID(sha,CLIENT_ID); |
| BLS24.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=BLS24.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=BLS24.MPIN_HASH_ID(sha,CLIENT_ID) |
| BLS24.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. */ |
| BLS24.MPIN_SERVER_1(sha,date,CLIENT_ID,pHID,pHTID) |
| |
| /* Server generates Random number Y and sends it to Client */ |
| BLS24.MPIN_RANDOM_GENERATE(rng,Y[:]); |
| |
| if FULL { |
| HSID=BLS24.MPIN_HASH_ID(sha,CLIENT_ID); |
| BLS24.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=BLS24.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=BLS24.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 == BLS24.BAD_PIN { |
| fmt.Printf("Server says - Bad Pin. I don't know you. Feck off.\n") |
| if PINERROR { |
| err:=BLS24.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:=BLS24.MPIN_HASH_ALL(sha,HCID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BLS24.MPIN_CLIENT_KEY(sha,G1[:],G2[:],pin,R[:],X[:],H[:],T[:],CK[:]) |
| fmt.Printf("Client Key = 0x"); printBinary(CK[:]) |
| |
| H=BLS24.MPIN_HASH_ALL(sha,HSID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BLS24.MPIN_SERVER_KEY(sha,Z[:],SST[:],W[:],H[:],pHID,pxID,pxCID,SK[:]) |
| fmt.Printf("Server Key = 0x"); printBinary(SK[:]) |
| } |
| } |
| } |
| |
| func mpin_BLS48(rng *amcl.RAND) { |
| |
| var sha=BLS48.HASH_TYPE |
| |
| const MGS=BLS48.MGS |
| const MFS=BLS48.MFS |
| const G1S=2*MFS+1 /* Group 1 Size */ |
| const G2S=16*MFS; /* Group 2 Size */ |
| |
| var S [MGS]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 [MGS]byte |
| var Y [MGS]byte |
| var E [48*MFS]byte |
| var F [48*MFS]byte |
| var HID [G1S]byte |
| var HTID [G1S]byte |
| |
| var G1 [48*MFS]byte |
| var G2 [48*MFS]byte |
| var R [MGS]byte |
| var Z [G1S]byte |
| var W [MGS]byte |
| var T [G1S]byte |
| var CK [BLS48.AESKEY]byte |
| var SK [BLS48.AESKEY]byte |
| |
| var HSID []byte |
| |
| |
| /* Trusted Authority set-up */ |
| |
| fmt.Printf("\nTesting MPIN\n") |
| BLS48.MPIN_RANDOM_GENERATE(rng,S[:]) |
| fmt.Printf("Master Secret s: 0x"); printBinary(S[:]) |
| |
| /* Create Client Identity */ |
| IDstr:= "testUser@miracl.com" |
| CLIENT_ID:=[]byte(IDstr) |
| |
| HCID:=BLS48.MPIN_HASH_ID(sha,CLIENT_ID) /* Either Client or TA calculates Hash(ID) - you decide! */ |
| |
| fmt.Printf("Client ID= "); printBinary(CLIENT_ID) |
| fmt.Printf("\n") |
| |
| /* Client and Server are issued secrets by DTA */ |
| BLS48.MPIN_GET_SERVER_SECRET(S[:],SST[:]) |
| fmt.Printf("Server Secret SS: 0x"); printBinary(SST[:]) |
| |
| BLS48.MPIN_GET_CLIENT_SECRET(S[:],HCID,TOKEN[:]) |
| fmt.Printf("Client Secret CS: 0x"); |
| printBinary(TOKEN[:]) |
| |
| /* Client extracts PIN from secret to create Token */ |
| pin:=1234 |
| fmt.Printf("Client extracts PIN= %d",pin) |
| fmt.Printf("\n") |
| rtn:=BLS48.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") |
| printBinary(TOKEN[:]); |
| |
| if FULL { |
| BLS48.MPIN_PRECOMPUTE(TOKEN[:],HCID,G1[:],G2[:]) |
| } |
| |
| date:=0 |
| if PERMITS { |
| date=BLS48.Today() |
| /* Client gets "Time Token" permit from DTA */ |
| BLS48.MPIN_GET_CLIENT_PERMIT(sha,date,S[:],HCID,PERMIT[:]) |
| fmt.Printf("Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| |
| /* This encoding makes Time permit look random - Elligator squared */ |
| BLS48.MPIN_ENCODING(rng,PERMIT[:]) |
| fmt.Printf("Encoded Time Permit TP: 0x"); printBinary(PERMIT[:]) |
| BLS48.MPIN_DECODING(PERMIT[:]) |
| fmt.Printf("Decoded Time Permit TP: 0x"); 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:= BLS48.MPIN_GET_TIME() |
| rtn=BLS48.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=BLS48.MPIN_HASH_ID(sha,CLIENT_ID) |
| BLS48.MPIN_GET_G1_MULTIPLE(rng,1,R[:],HCID,Z[:]) /* Also Send Z=r.ID to Server, remember random r */ |
| } |
| |
| rtn=BLS48.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=BLS48.MPIN_HASH_ID(sha,CLIENT_ID); |
| BLS48.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=BLS48.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=BLS48.MPIN_HASH_ID(sha,CLIENT_ID) |
| BLS48.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. */ |
| BLS48.MPIN_SERVER_1(sha,date,CLIENT_ID,pHID,pHTID) |
| |
| /* Server generates Random number Y and sends it to Client */ |
| BLS48.MPIN_RANDOM_GENERATE(rng,Y[:]); |
| |
| if FULL { |
| HSID=BLS48.MPIN_HASH_ID(sha,CLIENT_ID); |
| BLS48.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=BLS48.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=BLS48.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 == BLS48.BAD_PIN { |
| fmt.Printf("Server says - Bad Pin. I don't know you. Feck off.\n") |
| if PINERROR { |
| err:=BLS48.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:=BLS48.MPIN_HASH_ALL(sha,HCID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BLS48.MPIN_CLIENT_KEY(sha,G1[:],G2[:],pin,R[:],X[:],H[:],T[:],CK[:]) |
| fmt.Printf("Client Key = 0x"); printBinary(CK[:]) |
| |
| H=BLS48.MPIN_HASH_ALL(sha,HSID[:],pxID,pxCID,SEC[:],Y[:],Z[:],T[:]); |
| BLS48.MPIN_SERVER_KEY(sha,Z[:],SST[:],W[:],H[:],pHID,pxID,pxCID,SK[:]) |
| fmt.Printf("Server Key = 0x"); printBinary(SK[:]) |
| } |
| } |
| } |
| |
| func rsa_2048(rng *amcl.RAND) { |
| var sha=RSA2048.RSA_HASH_TYPE |
| message:="Hello World\n" |
| |
| pub:=RSA2048.New_public_key(RSA2048.FFLEN) |
| priv:=RSA2048.New_private_key(RSA2048.HFLEN) |
| |
| var ML [RSA2048.RFS]byte |
| var C [RSA2048.RFS]byte |
| var S [RSA2048.RFS]byte |
| |
| fmt.Printf("\nTesting RSA 2048-bit\n") |
| fmt.Printf("Generating public/private key pair\n") |
| RSA2048.RSA_KEY_PAIR(rng,65537,priv,pub) |
| |
| M:=[]byte(message) |
| |
| fmt.Printf("Encrypting test string\n") |
| E:=RSA2048.RSA_OAEP_ENCODE(sha,M,rng,nil) /* OAEP encode message M to E */ |
| |
| RSA2048.RSA_ENCRYPT(pub,E,C[:]) /* encrypt encoded message */ |
| fmt.Printf("Ciphertext= 0x"); printBinary(C[:]) |
| |
| fmt.Printf("Decrypting test string\n"); |
| RSA2048.RSA_DECRYPT(priv,C[:],ML[:]) |
| MS:=RSA2048.RSA_OAEP_DECODE(sha,nil,ML[:]) /* OAEP decode message */ |
| |
| message=string(MS) |
| fmt.Printf(message) |
| |
| fmt.Printf("Signing message\n") |
| RSA2048.RSA_PKCS15(sha,M,C[:]); |
| |
| RSA2048.RSA_DECRYPT(priv,C[:],S[:]) /* create signature in S */ |
| |
| fmt.Printf("Signature= 0x"); printBinary(S[:]) |
| |
| RSA2048.RSA_ENCRYPT(pub,S[:],ML[:]) |
| |
| cmp:=true |
| if len(C)!=len(ML) { |
| cmp=false |
| } else { |
| for j:=0;j<len(C);j++ { |
| if C[j]!=ML[j] {cmp=false} |
| } |
| } |
| if cmp { |
| fmt.Printf("Signature is valid\n") |
| } else { |
| fmt.Printf("Signature is INVALID\n") |
| } |
| |
| } |
| |
| func main() { |
| rng:=amcl.NewRAND() |
| var raw [100]byte |
| for i:=0;i<100;i++ {raw[i]=byte(i+1)} |
| rng.Seed(100,raw[:]) |
| |
| mpin_BN254(rng) |
| mpin_BLS383(rng) |
| mpin_BLS24(rng) |
| mpin_BLS48(rng) |
| ecdh_ED25519(rng) |
| ecdh_NIST256(rng) |
| ecdh_GOLDILOCKS(rng) |
| rsa_2048(rng) |
| } |