## File: README.md

# GameNetworkingSockets
[](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/build-ubuntu.yml) [](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/build-windows.yml) [](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/macos.yml) [](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/soak.yml) [](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/linux-flavors.yml)

GameNetworkingSockets is a basic transport layer for games.  The features are:

* Connection-oriented API (like TCP)
* ... but message-oriented (like UDP), not stream-oriented.
* Supports both reliable and unreliable message types
* Messages can be larger than underlying MTU.  The protocol performs
  fragmentation, reassembly, and retransmission for reliable messages.
* A [reliability layer](src/steamnetworkingsockets/clientlib/SNP_WIRE_FORMAT.md)
  significantly more sophisticated than a basic TCP-style sliding window.
  It is based on the "ack vector" model from DCCP (RFC 4340, section 11.4)
  and Google QUIC and discussed in the context of games by
  [Glenn Fiedler](https://gafferongames.com/post/reliable_ordered_messages/).
  The basic idea is for the receiver to efficiently communicate to the sender
  the status of every packet number (whether or not a packet was received
  with that number).  By remembering which segments were sent in each packet,
  the sender can deduce which segments need to be retransmitted.
* Encryption. AES-GCM-256 per packet, [Curve25519](https://cr.yp.to/ecdh.html) for
  key exchange and cert signatures. The details for shared key derivation and
  per-packet IV are based on the [design](https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing)
  used by Google's QUIC protocol.
* Tools for simulating packet latency/loss, and detailed stats measurement
* Head-of-line blocking control and bandwidth sharing of multiple message
  streams ("lanes") on the same connection.  You can use strict priority
  values, softer [weight values](https://en.wikipedia.org/wiki/Weighted_fair_queueing)
  that control how bandwidth is shared, or some combination of the two methods.
  See [``ISteamNetworkingSockets::ConfigureConnectionLanes``](include/steam/isteamnetworkingsockets.h).
* IPv6 support
* Peer-to-peer networking:
  * NAT traversal through google WebRTC's ICE implementation.
  * Plug in your own signaling service.
  * Unique "symmetric connect" mode.
  * [``ISteamNetworkingMessages``](include/steam/isteamnetworkingmessages.h) is an
    interface designed to make it easy to port UDP-based code to P2P use cases.  (By
    UDP-based, we mean non-connection-oriented code, where each time you send a
    packet, you specify the recipient's address.)
  * See [README_P2P.md](README_P2P.md) for more info
* Cross platform.  This library has shipped on consoles, mobile platforms, and non-Steam
  stores, and has been used to facilitate cross-platform connectivity.  Contact us to get
  access to the code.  (We are not allowed to distribute it here.)

What it does *not* do:

* Higher level serialization of entities, delta encoding of changed state
  variables, etc
* Compression

## Quick API overview

To get an idea of what the API is like, here are a few things to check out:

* The [include/steam](include/steam) folder has the public API headers.
  * [``ISteamNetworkingSockets``](include/steam/isteamnetworkingsockets.h) is the
    most important interface.
  * [``steamnetworkingtypes.h``](include/steam/steamnetworkingtypes.h) has misc
    types and declarations.
* The
  [Steamworks SDK documentation](https://partner.steamgames.com/doc/api/ISteamNetworkingSockets)
  offers web-based documentation for these APIs.  Note that some features
  are only available on Steam, such as Steam's authentication service,
  signaling service, and the SDR relay service.
* Look at these examples:
  * [example_chat.cpp](examples/example_chat.cpp).  Very simple client/server
    program using all reliable messages over ordinary IPv4.
  * [test_p2p.cpp](tests/test_p2p.cpp).  Shows how to get two hosts to connect
    to each other using P2P connectivity.  Also an example of how to write a
    signaling service plugin.

## Building

See [BUILDING](BUILDING.md) for more information.

## Language bindings

The library was written in C++, but there is also a plain C interface
to facilitate binding to other languages.

Third party language bindings:

* C#:
  * <https://github.com/nxrighthere/ValveSockets-CSharp>
  * <https://github.com/Facepunch/Facepunch.Steamworks>
* Go:
  * <https://github.com/nielsAD/gns/>
* Rust:
  * <https://github.com/hussein-aitlahcen/gns-rs>

## Why do I see "Steam" everywhere?

The main interface class is named SteamNetworkingSockets, and many files have
"steam" in their name.  But *Steam is not needed*.  If you don't make games or
aren't on Steam, feel free to use this code for whatever purpose you want.

The reason for "Steam" in the names is that this provides a subset of the
functionality of the [API](https://partner.steamgames.com/doc/api/ISteamNetworkingSockets)
with the same name in the Steamworks SDK.  Our main
reason for releasing this code is so that developers won't have any hesitation
coding to the API in the Steamworks SDK.  On Steam, you will link against the
Steamworks version, and you can access the additional services provided by
the [Steam Datagram Relay](https://partner.steamgames.com/doc/features/multiplayer/steamdatagramrelay)
network.  On other platforms and stores, as long as you ship a version of your
game on Steam, you might be able to take advantage of these services.  See
the Steamworks documentation for more information.  Because this is a live
service, and we need to control our security and backward compatibility burden,
at this time we are not able to offer access to SDR on other platforms to all
partners.

If you aren't a Steam partner, or don't have a version of your game on Steam,
then use this opensource version of the API and take advantage of the permissive
license to do whatever you want.  We want you to take maximum advantage of the
features in the Steamworks version.  That won't happen if this API is a weird
"wart" that's hidden behind `#ifdef STEAM`, which is why we're making this
opensource version available.

The desire to match the Steamworks SDK also explains a somewhat anachronistic
coding style and weird directory layout.  This project is kept in sync with the
Steam code here at Valve.  When we extracted the code from the much larger
codebase, we had to do some relatively gross hackery.  The files in folders
named  `tier0`, `tier1`, `vstdlib`, `common`, etc have especially suffered
trauma.  Also if you see code that appears to have unnecessary layers of
abstraction, it's probably because those layers are needed to support relayed
connection types or some part of the Steamworks SDK.

## Security

Did you find a security vulnerability?  Please inform us responsibly; you may
be eligible for a bug bounty.  See the [security policy](SECURITY.md) for more
information.

---

## File: examples/vcpkg_example_chat/README.md

The purpose of this project is to demonstrate/test a project that pulls in
GameNetworkingSockets and its dependencies entirely using vcpkg.

# TL;DR

We assume that your project defines its dependences in a `vcpkg.json` file, and
you are pulling in vcpkg's cmake toolchain file.  Then all you need to do is:

* Add `gamenetworkingsockets` as a dependency in your project's `vcpkg.json`
* In your cmake file, add `find_package( GameNetworkingSockets )`
* Link your targets with the appropriate library:
  * `target_link_libraries(<your_target> GameNetworkingSockets::shared)`
  * or `target_link_libraries(<your_target> GameNetworkingSockets::static)`

# Building the example project using vcpkg in manifest mode

Here are some specific instructions that build the example project using vcpkg in
["manifest mode"](https://vcpkg.readthedocs.io/en/latest/users/manifests/).
This example assumes Windows, and also it's recommended to run this from a
Visual Studio command prompt so we know what compiler to use.

First, we bootstrap a project-specific installation of vcpkg ("manifest mode")
in the default location, `/vcpkg`.  From the project root, run these
commands:

```
> git clone https://github.com/microsoft/vcpkg
> .\vcpkg\bootstrap-vcpkg.bat
```

Now we ask vcpkg to install of the dependencies for our project, which are described by
the file `/vcpkg.json`.  Note that this step is optional, as cmake will
automatically do this.  But here we are doing it in a separate step so that we can isolate
any problems, because if problems happen here don't have anything to do with your
cmake files.

```
> .\vcpkg\vcpkg install --triplet=x64-windows
```

Next build the project files.  There are different options for telling cmake how
to integrate with vcpkg; here we use `CMAKE_TOOLCHAIN_FILE` on the command line.
Also we select Ninja project generator.

```
> cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=vcpkg\scripts\buildsystems\vcpkg.cmake
```

Finally, build the project:

```
> cd build
> ninja
```

---

## File: src/external/ed25519-donna/fuzz/README.md

This code fuzzes ed25519-donna (and optionally ed25519-donna-sse2) against the ref10 implementations of
[curve25519](https://github.com/floodyberry/supercop/tree/master/crypto_scalarmult/curve25519/ref10) and 
[ed25519](https://github.com/floodyberry/supercop/tree/master/crypto_sign/ed25519/ref10).

Curve25519 tests that generating a public key from a secret key

# Building

## *nix + PHP

`php build-nix.php (required parameters) (optional parameters)`

Required parameters:

* `--function=[curve25519,ed25519]`
* `--bits=[32,64]`

Optional parameters:

* `--with-sse2`

    Also fuzz against ed25519-donna-sse2
* `--with-openssl`

    Build with OpenSSL's SHA-512.

    Default: Reference SHA-512 implementation (slow!)

* `--compiler=[gcc,clang,icc]`

    Default: gcc

* `--no-asm`

    Do not use platform specific assembler


example:
    
    php build-nix.php --bits=64 --function=ed25519 --with-sse2 --compiler=icc 

## Windows

Create a project with access to the ed25519 files.

If you are not using OpenSSL, add the `ED25519_REFHASH` define to the projects 
"Properties/Preprocessor/Preprocessor Definitions" option

Add the following files to the project:

* `fuzz/curve25519-ref10.c`
* `fuzz/ed25519-ref10.c`
* `fuzz/ed25519-donna.c`
* `fuzz/ed25519-donna-sse2.c` (optional)
* `fuzz-[curve25519/ed25519].c` (depending on which you want to fuzz)

If you are also fuzzing against ed25519-donna-sse2, add the `ED25519_SSE2` define for `fuzz-[curve25519/ed25519].c` under 
its "Properties/Preprocessor/Preprocessor Definitions" option.

# Running

If everything agrees, the program will only output occasional status dots (every 0x1000 passes) 
and a 64bit progress count (every 0x20000 passes):

    fuzzing:  ref10 curved25519 curved25519-sse2
    
    ................................ [0000000000020000]
    ................................ [0000000000040000]
    ................................ [0000000000060000]
    ................................ [0000000000080000]
    ................................ [00000000000a0000]
    ................................ [00000000000c0000]
 
If any of the implementations do not agree with the ref10 implementation, the program will dump
the random data that was used, the data generated by the ref10 implementation, and diffs of the 
ed25519-donna data against the ref10 data.

## Example errors

These are example error dumps (with intentionally introduced errors).

### Ed25519

Random data:

* sk, or Secret Key
* m, or Message

Generated data:

* pk, or Public Key
* sig, or Signature
* valid, or if the signature of the message is valid with the public key

Dump:

    sk:
    0x3b,0xb7,0x17,0x7a,0x66,0xdc,0xb7,0x9a,0x90,0x25,0x07,0x99,0x96,0xf3,0x92,0xef,
    0x78,0xf8,0xad,0x6c,0x35,0x87,0x81,0x67,0x03,0xe6,0x95,0xba,0x06,0x18,0x7c,0x9c,
    
    m:
    0x7c,0x8d,0x3d,0xe1,0x92,0xee,0x7a,0xb8,0x4d,0xc9,0xfb,0x02,0x34,0x1e,0x5a,0x91,
    0xee,0x01,0xa6,0xb8,0xab,0x37,0x3f,0x3d,0x6d,0xa2,0x47,0xe3,0x27,0x93,0x7c,0xb7,
    0x77,0x07,0xb6,0x88,0x41,0x22,0xf3,0x3f,0xce,0xcb,0x6b,0x3e,0x2b,0x23,0x68,0x7f,
    0x5b,0xb9,0xda,0x04,0xbb,0xae,0x42,0x50,0xf5,0xe9,0xc5,0x11,0xbd,0x52,0x76,0x98,
    0xf1,0x87,0x09,0xb9,0x89,0x0a,0x52,0x69,0x01,0xce,0xe0,0x4a,0xa6,0x46,0x5a,0xe1,
    0x63,0x14,0xe0,0x81,0x52,0xec,0xcd,0xcf,0x70,0x54,0x7d,0xa3,0x49,0x8b,0xf0,0x89,
    0x70,0x07,0x12,0x2a,0xd9,0xaa,0x16,0x01,0xb2,0x16,0x3a,0xbb,0xfc,0xfa,0x13,0x5b,
    0x69,0x83,0x92,0x70,0x95,0x76,0xa0,0x8e,0x16,0x79,0xcc,0xaa,0xb5,0x7c,0xf8,0x7a,
    
    ref10:
    pk:
    0x71,0xb0,0x5e,0x62,0x1b,0xe3,0xe7,0x36,0x91,0x8b,0xc0,0x13,0x36,0x0c,0xc9,0x04,
    0x16,0xf5,0xff,0x48,0x0c,0x83,0x6b,0x88,0x53,0xa2,0xc6,0x0f,0xf7,0xac,0x42,0x04,
    
    sig:
    0x3e,0x05,0xc5,0x37,0x16,0x0b,0x29,0x30,0x89,0xa3,0xe7,0x83,0x08,0x16,0xdd,0x96,
    0x02,0xfa,0x0d,0x44,0x2c,0x43,0xaa,0x80,0x93,0x04,0x58,0x22,0x09,0xbf,0x11,0xa5,
    0xcc,0xa5,0x3c,0x9f,0xa0,0xa4,0x64,0x5a,0x4a,0xdb,0x20,0xfb,0xc7,0x9b,0xfd,0x3f,
    0x08,0xae,0xc4,0x3c,0x1e,0xd8,0xb6,0xb4,0xd2,0x6d,0x80,0x92,0xcb,0x71,0xf3,0x02,
    
    valid: yes
    
    ed25519-donna:
    pk diff:
    ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
    ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
    
    sig diff:
    0x2c,0xb9,0x25,0x14,0xd0,0x94,0xeb,0xfe,0x46,0x02,0xc2,0xe8,0xa3,0xeb,0xbf,0xb5,
    0x72,0x84,0xbf,0xc1,0x8a,0x32,0x30,0x99,0xf7,0x58,0xfe,0x06,0xa8,0xdc,0xdc,0xab,
    0xb5,0x57,0x03,0x33,0x87,0xce,0x54,0x55,0x6a,0x69,0x8a,0xc4,0xb7,0x2a,0xed,0x97,
    0xb4,0x68,0xe7,0x52,0x7a,0x07,0x55,0x3b,0xa2,0x94,0xd6,0x5e,0xa1,0x61,0x80,0x08,
    
    valid: no

In this case, the generated public key matches, but the generated signature is completely 
different and does not validate.

### Curve25519

Random data:

* sk, or Secret Key

Generated data:

* pk, or Public Key

Dump:

    sk:
    0x44,0xec,0x0b,0x0e,0xa2,0x0e,0x9c,0x5b,0x8c,0xce,0x7b,0x1d,0x68,0xae,0x0f,0x9e,
    0x81,0xe2,0x04,0x76,0xda,0x87,0xa4,0x9e,0xc9,0x4f,0x3b,0xf9,0xc3,0x89,0x63,0x70,
    
    
    ref10:
    0x24,0x55,0x55,0xc0,0xf9,0x80,0xaf,0x02,0x43,0xee,0x8c,0x7f,0xc1,0xad,0x90,0x95,
    0x57,0x91,0x14,0x2e,0xf2,0x14,0x22,0x80,0xdd,0x4e,0x3c,0x85,0x71,0x84,0x8c,0x62,
    
    
    curved25519 diff:
    0x12,0xd1,0x61,0x2b,0x16,0xb3,0xd8,0x29,0xf8,0xa3,0xba,0x70,0x4e,0x49,0x4f,0x43,
    0xa1,0x3c,0x6b,0x42,0x11,0x61,0xcc,0x30,0x87,0x73,0x46,0xfb,0x85,0xc7,0x9a,0x35,
    
    
    curved25519-sse2 diff:
    ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
    ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,


In this case, curved25519 is totally wrong, while curved25519-sse2 matches the reference 
implementation.

---

## File: src/external/ed25519-donna/README.md

[ed25519](http://ed25519.cr.yp.to/) is an 
[Elliptic Curve Digital Signature Algortithm](http://en.wikipedia.org/wiki/Elliptic_Curve_DSA), 
developed by [Dan Bernstein](http://cr.yp.to/djb.html), 
[Niels Duif](http://www.nielsduif.nl/), 
[Tanja Lange](http://hyperelliptic.org/tanja), 
[Peter Schwabe](http://www.cryptojedi.org/users/peter/), 
and [Bo-Yin Yang](http://www.iis.sinica.edu.tw/pages/byyang/).

This project provides performant, portable 32-bit & 64-bit implementations. All implementations are 
of course constant time in regard to secret data.

#### Performance

SSE2 code and benches have not been updated yet. I will do those next.

Compilers versions are gcc 4.6.3, icc 13.1.1, clang 3.4-1~exp1.

Batch verfication time (in parentheses) is the average time per 1 verification in a batch of 64 signatures. Counts are in thousands of cycles.

Note that SSE2 performance may be less impressive on AMD & older CPUs with slower SSE ops!

Visual Studio performance for `ge25519_scalarmult_base_niels` will lag behind a bit until optimized assembler versions of `ge25519_scalarmult_base_choose_niels`
are made.

##### E5200 @ 2.5ghz, march=core2



| Implementation | Sign | gcc | icc | clang | Verify | gcc | icc | clang |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ed25519-donna 64bit |  | 100k | 110k | 137k |  | 327k (144k) | 342k (163k) | 422k (194k) |
| amd64-64-24k |  | 102k |  |  |  | 355k (158k) |  |  |
| ed25519-donna-sse2 64bit |  | 108k | 111k | 116k |  | 353k (155k) | 345k (154k) | 360k (161k) |
| amd64-51-32k |  | 116k |  |  |  | 380k (175k) |  |  |
| ed25519-donna-sse2 32bit |  | 147k | 147k | 156k |  | 380k (178k) | 381k (173k) | 430k (192k) |
| ed25519-donna 32bit |  | 597k | 335k | 380k |  | 1693k (720k) | 1052k (453k) | 1141k (493k) |



##### E3-1270 @ 3.4ghz, march=corei7-avx



| Implementation | Sign | gcc | icc | clang | Verify | gcc | icc | clang |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| amd64-64-24k |  | 68k |  |  |  | 225k (104k) |  |  |
| ed25519-donna 64bit |  | 71k | 75k | 90k |  | 226k (105k) | 226k (112k) | 277k (125k) |
| amd64-51-32k |  | 72k |  |  |  | 218k (107k) |  |  |
| ed25519-donna-sse2 64bit |  | 79k | 82k | 92k |  | 252k (122k) | 259k (124k) | 282k (131k) |
| ed25519-donna-sse2 32bit |  | 94k | 95k | 103k |  | 296k (146k) | 294k (137k) | 306k (147k) |
| ed25519-donna 32bit |  | 525k | 299k | 316k |  | 1502k (645k) | 959k (418k) | 954k (416k) |



#### Compilation

No configuration is needed **if you are compiling against OpenSSL**. 

##### Hash Options

If you are not compiling aginst OpenSSL, you will need a hash function.

To use a simple/**slow** implementation of SHA-512, use `-DED25519_REFHASH` when compiling `ed25519.c`. 
This should never be used except to verify the code works when OpenSSL is not available.

To use a custom hash function, use `-DED25519_CUSTOMHASH` when compiling `ed25519.c` and put your 
custom hash implementation in ed25519-hash-custom.h. The hash must have a 512bit digest and implement

	struct ed25519_hash_context;

	void ed25519_hash_init(ed25519_hash_context *ctx);
	void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
	void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
	void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);

##### Random Options

If you are not compiling aginst OpenSSL, you will need a random function for batch verification.

To use a custom random function, use `-DED25519_CUSTOMRANDOM` when compiling `ed25519.c` and put your 
custom hash implementation in ed25519-randombytes-custom.h. The random function must implement:

	void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len);

Use `-DED25519_TEST` when compiling `ed25519.c` to use a deterministically seeded, non-thread safe CSPRNG 
variant of Bob Jenkins [ISAAC](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29)

##### Minor options

Use `-DED25519_INLINE_ASM` to disable the use of custom assembler routines and instead rely on portable C.

Use `-DED25519_FORCE_32BIT` to force the use of 32 bit routines even when compiling for 64 bit.

##### 32-bit

	gcc ed25519.c -m32 -O3 -c

##### 64-bit

	gcc ed25519.c -m64 -O3 -c

##### SSE2

	gcc ed25519.c -m32 -O3 -c -DED25519_SSE2 -msse2
	gcc ed25519.c -m64 -O3 -c -DED25519_SSE2

clang and icc are also supported


#### Usage

To use the code, link against `ed25519.o -mbits` and:

	#include "ed25519.h"

Add `-lssl -lcrypto` when using OpenSSL (Some systems don't need -lcrypto? It might be trial and error).

To generate a private key, simply generate 32 bytes from a secure
cryptographic source:

	ed25519_secret_key sk;
	randombytes(sk, sizeof(ed25519_secret_key));

To generate a public key:

	ed25519_public_key pk;
	ed25519_publickey(sk, pk);

To sign a message:

	ed25519_signature sig;
	ed25519_sign(message, message_len, sk, pk, signature);

To verify a signature:

	int valid = ed25519_sign_open(message, message_len, pk, signature) == 0;

To batch verify signatures:

	const unsigned char *mp[num] = {message1, message2..}
	size_t ml[num] = {message_len1, message_len2..}
	const unsigned char *pkp[num] = {pk1, pk2..}
	const unsigned char *sigp[num] = {signature1, signature2..}
	int valid[num]

	/* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */
	int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0;

**Note**: Batch verification uses `ed25519_randombytes_unsafe`, implemented in 
`ed25519-randombytes.h`, to generate random scalars for the verification code. 
The default implementation now uses OpenSSLs `RAND_bytes`.

Unlike the [SUPERCOP](http://bench.cr.yp.to/supercop.html) version, signatures are
not appended to messages, and there is no need for padding in front of messages. 
Additionally, the secret key does not contain a copy of the public key, so it is 
32 bytes instead of 64 bytes, and the public key must be provided to the signing
function.

##### Curve25519

Curve25519 public keys can be generated thanks to 
[Adam Langley](http://www.imperialviolet.org/2013/05/10/fastercurve25519.html) 
leveraging Ed25519's precomputed basepoint scalar multiplication.

	curved25519_key sk, pk;
	randombytes(sk, sizeof(curved25519_key));
	curved25519_scalarmult_basepoint(pk, sk);

Note the name is curved25519, a combination of curve and ed25519, to prevent 
name clashes. Performance is slightly faster than short message ed25519
signing due to both using the same code for the scalar multiply.

#### Testing

Fuzzing against reference implemenations is now available. See [fuzz/README](fuzz/README.md).

Building `ed25519.c` with `-DED25519_TEST` and linking with `test.c` will run basic sanity tests
and benchmark each function. `test-batch.c` has been incorporated in to `test.c`.

`test-internals.c` is standalone and built the same way as `ed25519.c`. It tests the math primitives
with extreme values to ensure they function correctly. SSE2 is now supported.

#### Papers

[Available on the Ed25519 website](http://ed25519.cr.yp.to/papers.html)

---

## File: src/external/curve25519-donna/README.md

[curve25519](http://cr.yp.to/ecdh.html) is an elliptic curve, developed by 
[Dan Bernstein](http://cr.yp.to/djb.html), for fast 
[Diffie-Hellman](http://en.wikipedia.org/wiki/Diffie-Hellman) key agreement. 
DJB's [original implementation](http://cr.yp.to/ecdh.html) was written in a 
language of his own devising called [qhasm](http://cr.yp.to/qhasm.html). 
The original qhasm source isn't available, only the x86 32-bit assembly output.

This project provides performant, portable 32-bit & 64-bit implementations. 
All implementations are of course constant time in regard to secret data.

#### Performance 

Compilers versions are gcc 4.6.3, icc 13.1.1, clang 3.4-1~exp1.

Counts are in thousands of cycles.

Note that SSE2 performance may be less impressive on AMD & older CPUs with slower SSE ops!

##### E5200 @ 2.5ghz, march=core2



| Version | gcc | icc | clang |
| --- | --- | --- | --- |
| 64-bit SSE2 | 278k | 265k | 302k |
| 64-bit | 273k | 271k | 377k |
| 32-bit SSE2 | 304k | 289k | 317k |
| 32-bit | 1417k | 845k | 981k |



##### E3-1270 @ 3.4ghz, march=corei7-avx



| Version | gcc | icc | clang |
| --- | --- | --- | --- |
| 64-bit | 201k | 192k | 233k |
| 64-bit SSE2 | 201k | 201k | 261k |
| 32-bit SSE2 | 238k | 225k | 250k |
| 32-bit | 1293k | 822k | 848k |



#### Compilation

No configuration is needed.

##### 32-bit

	gcc curve25519.c -m32 -O3 -c

##### 64-bit

	gcc curve25519.c -m64 -O3 -c

##### SSE2

	gcc curve25519.c -m32 -O3 -c -DCURVE25519_SSE2 -msse2
	gcc curve25519.c -m64 -O3 -c -DCURVE25519_SSE2

clang, icc, and msvc are also supported

##### Named Versions

Define CURVE25519_SUFFIX to append a suffix to public functions, e.g. 
`-DCURVE25519_SUFFIX=_sse2` to create curve25519_donna_sse2 and 
curve25519_donna_basepoint_sse2.

#### Usage

To use the code, link against `curve25519.o` and:

	#include "curve25519.h"

To generate a private/secret key, generate 32 cryptographically random bytes: 

	curve25519_key sk;
	randombytes(sk, sizeof(curve25519_key));

Manual clamping is not needed, and it is actually not possible to use unclamped
keys due to the code taking advantage of the clamped bits internally.

To generate the public key from the private/secret key:

	curve25519_key pk;
	curve25519_donna_basepoint(pk, sk);

To generate a shared key with your private/secret key and someone elses public key:

	curve25519_key shared;
	curve25519_donna(shared, mysk, yourpk);

And hash `shared` with a cryptographic hash before using, or e.g. pass `shared` through
HSalsa20/HChacha as NaCl does.

#### Testing

Fuzzing against a reference implemenation is now available. See [fuzz/README](fuzz/README.md).

Building `curve25519.c` and linking with `test.c` will run basic sanity tests and benchmark curve25519_donna.

#### Papers

[djb's curve25519 paper](http://cr.yp.to/ecdh/curve25519-20060209.pdf)

#### License

Public Domain, or MIT

---

## File: README_P2P.md

# About that P2P support....

SteamNetworkingSockets supports peer-to-peer connections.  A "peer-to-peer"
connection in this context means that the hosts do not (initially) know
each other's IP address.  Furthermore, they may be behind NAT, and so they
may not know their *own* public IP address.  They may not even *have* a public
IP that other hosts can use to send them inbound traffic.  [Here](https://tailscale.com/blog/how-nat-traversal-works/)
is a good article about the problem of NAT traversal.

[ICE](https://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment)
is an internet standard protocol for discovering and sharing IP addresses,
negotiating NAT, and establishing a direct connection or fallback to relaying
the connection if necessary.

The library includes an ICE client implementation with no external dependencies
that is compiled in by default.  (See the vcpkg feature `ice` or the cmake flag
`ENABLE_ICE`).

Alternatively, the library can also be compiled to use
[Google WebRTC](https://webrtc.googlesource.com/src)'s ICE implementation.
We interface with the WebRTC code at a relatively low level and only use it
for datagram transport.  We don't use DTLS or WebRTC data channels.
See also `k_ESteamNetworkingConfig_P2P_Transport_ICE_Implementation`.

The two candidates are compatible with one another.  (A peer using the WebRTC
ICE client can conneect to a peer using the native client.)

## Symmetric connect mode

SteamNetworkingSockets offers a unique feature known as *symmetric
connect mode*, which really puts the "peer" in "peer-to-peer connection".
This feature is useful in the following common use case:

* Two hosts wish to establish a *single* connection between them.
* Either host may initiate the connection.
* The hosts may initiate the connection at the same time.

This situation involves race conditions that can be tricky to get
right, especially when authentication, encryption, ICE roles, etc
are involved.  With symmetric connect mode, sorting out these race
conditions and producing a single connection is handled by the API.

See the ``k_ESteamNetworkingConfig_SymmetricConnect``
connection flag in [steamnetworkingtypes.h](include/steam/steamnetworkingtypes.h)
for more info.

## ISteamNetworkingMessages

Most P2P libraries, such as google WebRTC, and indeed our own
[ISteamNetworkingSockets](include/steam/isteamnetworkingsockets.h), are *connection
oriented*.  To talk to a peer, you first establish a connection to the peer, and
when you send and receive messages, the peer is identified by the connection handle.

Much existing network code is based on UDP with a single socket, where
 connection handles are not used.  Instead, packets are sent with the IP address
 of the recipeient specified for each packet.   (E.g. ``sentto()`` and ``recvfrom()``).
[ISteamNetworkingMessages](include/steam/isteamnetworkingmessages.h) was created
to provide a more "ad-hoc" interface like UDP.  It can be useful when adding P2P
support to existing code, depending on the abstraction you are working with.  If
the code you are modifing already has the concept of a connection, then you might
find it easier to use ISteamNetworkinSockets directly.  But if you are modifying code
at a lower level, you may find that you need to maintain a table of active connections,
and each time you send a packet, use the existing connection if one exists, or
create a new connection if one does not exist.  This is exactly what
ISteamNetworkingMessages does for you.  It creates symmetric-mode connections on
demand the first time you communicate with a given peer, and idle connections are
automatically closed when they are no longer needed.

## Requirements

Peer-to-peer connections require more than just working code.  In addition
to the code in this library, there are several other prerequisites.
(Note that the Steamworks API provides all of these services for Steam games.)

### Signaling service

A side channel, capable of relaying small rendezvous
messages from one host to another.  This means hosts must have a constant
connection to your service, once that enables you to *push* messages to them.

SteamNetworkingSockets supports a pluggable signaling service.  The requirements
placed on your signaling service are relatively minimal:

* Individual rendezvous messages are small.  (Perhaps bigger than IP MTU,
  but never more than a few KB.)
* Only datagram "best-effort" delivery is required.  The signaling protocol
  is tolerant of dropped, duplicated, or reordered messages.
  These anomalies may cause negotiation to take longer, but not fail.
  This means, for example that there doesn't need to be a mechanism to
  inform the system when your connection to the signaling service is
  disrupted.
* The channel can be relatively low bandwidth and high latency.  Usually
  there is a burst of a handful of exchanges when a connection is created,
  followed by silence, unless something changes with the connection.


### STUN server(s)

A [STUN](https://en.wikipedia.org/wiki/STUN) server is used to help peers
discover their own public IP address and open up firewalls.  STUN
servers are relatively low bandwidth, and there are publicly-available ones.

### Relay fallback

Unfortunatley, for some pairs of hosts, NAT piercing is not successful.
In this situation, the traffic must be relayed.  In the ICE protocol, this is
done using [TURN](https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT)
servers.  (NOTE: Any TURN server also doubles as a STUN server.)  Because the TURN
server is relaying every packet, is is a relatively costly service, so you probably
will need to run your own, or just fail connections that cannot pierce NAT.

On Steam we use a custom relay service known as [Steam Datgaram Relay](https://partner.steamgames.com/doc/features/multiplayer/steamdatagramrelay)
-- SDR for short -- carrying packets through our network of relays and
on our backbone.   (You may see this mentioned in the opensource code here,
but the SDR support code is not opensource.)  Also, on Steam we often
do not share public IP addresses between untrusted peers, so that malicious
players cannot DoS attack.  In that case NAT punch is not possible and traffic
would be relayed.

### Naming hosts and matchmaking

The above requirements are just what is needed to make a connection between two
hosts, once you know who to connect to.  But before that, you need a way to assign an
identity to a host, authenticate them, matchmaking them, etc.  Those services are
also included with Steam, but outside the scope of a transport library like this.

## Using P2P

Assuming you have all of those requirements, you can use SteamNetworkingSockets
to make P2P connections!

To enable P2P/ICE support, just use the vcpkg feature `ice`, or build with the cmake
flag `-DENABLE_ICE=ON`.  Note that both of these are the default, so you just need
to avoid explicitly turning it off.

If you want to use the Google WebRTC ICE implementation, set
`-DUSE_STEAMWEBRTC=ON`.  cmake will automatically activate two git submodules
and pull down the Google WebRTC code.

Take a look at these files for more information:

* [steamnetworkingcustomsignaling.h](include/steam/steamnetworkingcustomsignaling.h)
  contains the interfaces you'll need to implement for your signaling service.
* An example of a really trivial signaling protocol:
  * [trivial_signaling_server.py](examples/trivial_signaling_server.py) server
  * [trivial_signaling_client.cpp](examples/trivial_signaling_client.cpp) client
* A test case that puts everything together.  It starts up an example trivial
  signaling protocol server and two peers, and has them connect to each other
  and exchange a few messages.  We use the publicly-available google STUN servers.
  (No TURN servers for relay fallback in this example.)
  * [test_p2p.py](tests/test_p2p.py) Executive test script that starts all the processes.
  * [test_p2p.cpp](tests/test_p2p.cpp) Code for the process each peer runs.

## Roadmap

Here are some things we have in mind to make P2P support better:

* Get plugins written for standard, opensource protocols that could be used for
  signaling, such as [XMPP](https://xmpp.org/).  This would be a great project for
  somebody else to do!  We would welcome contributions to this repository, or
  happily link to your own project.  (See issue #136)
* LAN beacon support, so that P2P connections can be made even when signaling
  is down or the hosts do not have Internet connectivity.  (See issue #82)
* Support for [PCP](https://tools.ietf.org/html/rfc6887) as an additional
  NAT traversal mechanism.
* Shared candidate pool across multiple P2P connections.  Currently, each
  connection goes through a full ICE gathering process independently, including
  opening its own sockets and creating its own TURN allocation.  A server forming
  connections with many peers (e.g. a full mesh) could instead gather candidates
  once per interface, share a single set of sockets, and reuse a single TURN
  allocation across all peers.  This would be a significant efficiency improvement.
* TURN channels, for more efficient relay of data packets once a relayed path
  is selected.
* MTU probing: ICE connectivity checks should be sent at the full path MTU, so
  that MTU issues are discovered during negotiation rather than after the
  connection is established.