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  }