/
client_kem.go
80 lines (69 loc) · 2.07 KB
/
client_kem.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Key encapsulation TCP client Go example
package main
import (
"bufio"
"errors"
"fmt"
"io"
"log"
"net"
"os"
"github.com/open-quantum-safe/liboqs-go/oqs"
)
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: client_kem <address> <port number>")
os.Exit(1)
}
address := os.Args[1]
port := os.Args[2]
fmt.Println("Launching KEM client on", address+":"+port)
conn, err := net.Dial("tcp", address+":"+port)
if err != nil {
log.Fatal(errors.New("client cannot connect " +
"to " + address + ":" + port))
}
defer conn.Close() // clean up even in case of panic
// Construct the KEM client
client := oqs.KeyEncapsulation{}
defer client.Clean() // clean up even in case of panic
// Receive the KEM name from the server
kemName, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
log.Fatal(errors.New("client cannot receive the " +
"KEM name from the server"))
}
kemName = kemName[:len(kemName)-1] // remove the '\n'
// Initialize the KEM client and generate the key pairs
if err := client.Init(kemName, nil); err != nil {
log.Fatal(err)
}
clientPublicKey, err := client.GenerateKeyPair()
if err != nil {
log.Fatal(err)
}
// Send the client public key to the server
_, err = conn.Write(clientPublicKey)
if err != nil {
log.Fatal(errors.New("client cannot send the public key to the " +
"server"))
}
// Listen for reply from the server, e.g. for the encapsulated secret
ciphertext := make([]byte, client.Details().LengthCiphertext)
n, err := io.ReadFull(conn, ciphertext)
if err != nil {
log.Fatal(err)
} else if n != client.Details().LengthCiphertext {
log.Fatal(errors.New("client expected to read " +
fmt.Sprintf("%v", client.Details().LengthCiphertext) + " bytes, but instead " +
"read " + fmt.Sprintf("%v", n)))
}
// Decapsulate the secret and extract the shared secret
sharedSecretClient, err := client.DecapSecret(ciphertext)
if err != nil {
log.Fatal(err)
}
fmt.Println(client.Details())
fmt.Printf("\nClient shared secret:\n% X ... % X\n",
sharedSecretClient[0:8], sharedSecretClient[len(sharedSecretClient)-8:])
}