github.com/quantosnetwork/Quantos@v0.0.0-20220306172517-e20b28c5a29a/protocol/keyExchange.go (about) 1 package protocol 2 3 import ( 4 "bufio" 5 "errors" 6 "fmt" 7 "github.com/open-quantum-safe/liboqs-go/oqs" 8 "github.com/quantosnetwork/Quantos/crypto" 9 "io" 10 "log" 11 "net" 12 ) 13 14 const KEMNAME = "kyber512" 15 16 type keyExchange interface { 17 initKemKX(host, port string) 18 handleKemKX(conn net.Conn) 19 } 20 21 type KeyExchange struct { 22 conn net.Conn 23 clientKeys *crypto.KemKeys 24 serverKeys *crypto.ServerKeys 25 } 26 27 func (kex KeyExchange) initKemKX(host, port string) { 28 kex.clientKeys = crypto.NewKemClient() 29 kex.serverKeys = crypto.NewKemServer() 30 31 listener, err := net.Listen("tcp", host+":"+port) 32 if err != nil { 33 log.Fatal(err) 34 } 35 for { 36 kex.conn, err = listener.Accept() 37 38 if err != nil { 39 panic(err) 40 } 41 go kex.handleKemKX(kex.conn) 42 } 43 44 } 45 46 func (kex KeyExchange) handleKemKX(conn net.Conn) { 47 defer conn.Close() 48 _, err := fmt.Println(conn, KEMNAME) 49 if err != nil { 50 conn.Close() 51 } 52 clientPublicKey := make([]byte, kex.serverKeys.Server.Details().LengthPublicKey) 53 _, err = io.ReadFull(conn, clientPublicKey) 54 if err != nil { 55 conn.Write([]byte("could not read key\n")) 56 conn.Close() 57 return 58 } 59 cipherText, sharedSecret, _ := kex.serverKeys.Server.EncapSecret(clientPublicKey) 60 _, err = conn.Write(cipherText) 61 if err != nil { 62 log.Fatal(err) 63 return 64 } 65 log.Printf("\nConnection #%d - server shared secret:\n% X ... % X\n\n", sharedSecret[0:8], 66 sharedSecret[len(sharedSecret)-8:]) 67 68 conn.Write([]byte("AUTHENTICATED")) 69 } 70 71 func StartKeyExchange(host, port string) { 72 73 var kex KeyExchange 74 kex.initKemKX(host, port) 75 76 } 77 78 func StartKexClient() { 79 conn, err := net.Dial("tcp", "127.0.0.1:55225") 80 if err != nil { 81 log.Fatal(errors.New("client cannot connect " + 82 "to host on port 55225")) 83 } 84 defer conn.Close() 85 client := oqs.KeyEncapsulation{} 86 defer client.Clean() 87 kemName, err := bufio.NewReader(conn).ReadString('\n') 88 if err != nil { 89 panic(err) 90 log.Fatal(errors.New("client cannot receive the " + 91 "KEM name from the server")) 92 } 93 kemName = kemName[:len(kemName)-1] 94 if err := client.Init(kemName, nil); err != nil { 95 log.Fatal(err) 96 } 97 clientPublicKey, err := client.GenerateKeyPair() 98 if err != nil { 99 log.Fatal(err) 100 } 101 _, err = conn.Write(clientPublicKey) 102 if err != nil { 103 log.Fatal(errors.New("client cannot send the public key to the " + 104 "server")) 105 } 106 107 // listen for reply from the server, e.g. for the encapsulated secret 108 ciphertext := make([]byte, client.Details().LengthCiphertext) 109 n, err := io.ReadFull(conn, ciphertext) 110 if err != nil { 111 log.Fatal(err) 112 } else if n != client.Details().LengthCiphertext { 113 log.Fatal(errors.New("client expected to read " + 114 string(client.Details().LengthCiphertext) + " bytes, but instead " + 115 "read " + string(n))) 116 } 117 118 // decapsulate the secret and extract the shared secret 119 sharedSecretClient, err := client.DecapSecret(ciphertext) 120 if err != nil { 121 log.Fatal(err) 122 } 123 124 fmt.Println(client.Details()) 125 fmt.Printf("\nClient shared secret:\n% X ... % X\n", 126 sharedSecretClient[0:8], sharedSecretClient[len(sharedSecretClient)-8:]) 127 128 }