Skip to content

Instantly share code, notes, and snippets.

@AljoschaMeyer
Last active October 31, 2017 19:08
Show Gist options
  • Save AljoschaMeyer/bdcac0377fdef904119a52c41bd50871 to your computer and use it in GitHub Desktop.
Save AljoschaMeyer/bdcac0377fdef904119a52c41bd50871 to your computer and use it in GitHub Desktop.
js implementation of secret-handshake, with a focus on readability
const {
crypto_auth_verify,
crypto_auth,
crypto_scalarmult,
crypto_hash_sha256,
crypto_sign_ed25519_sk_to_curve25519,
crypto_sign_ed25519_pk_to_curve25519,
crypto_secretbox_open_easy,
crypto_sign_verify_detached,
crypto_sign_detached,
crypto_secretbox_easy
} = require('chloride');
/*
* Implementation of the crypto the client needs to perform.
*
* Note that the initial keys have different formats, ephemeral keys are curvified:
* - `client_longterm_sk`: crypto_sign_PUBLICKEYBYTES
* - `client_longterm_pk`: crypto_sign_SECRETKEYBYTES
* - `client_ephemeral_sk`: crypto_scalarmult_curve25519_BYTES (the result of crypto_sign_ed25519_sk_to_curve25519 on crypto_sign_SECRETKEYBYTES)
* - `client_ephemeral_pk`: crypto_scalarmult_curve25519_BYTES (the result of crypto_sign_ed25519_pk_to_curve25519 on crypto_sign_PUBLICKEYBYTES)
* - `server_longterm_pk`: crypto_sign_PUBLICKEYBYTES
*/
// At some points, the protocol needs 24 zero bytes in place of a nonce.
const zeros = Buffer.alloc(24);
zeros.fill(0);
// Returns a Buffer<64 bytes> containing a valid msg1.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `client_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
module.exports.createMsg1 = state => {
const hmac = crypto_auth(state.client_ephemeral_pk, state.network_identifier);
return Buffer.concat([hmac, state.client_ephemeral_pk]);
};
// Returns true iff `msg: Buffer<64 bytes>` is a valid msg2 for the given state.
// Also updates state if msg was valid.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
//
// After successfully validating, this adds a field to `state`:
// - `server_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
module.exports.verifyMsg2 = (state, msg) => {
const hmac = msg.slice(0, 32);
const server_ephemeral_pk = msg.slice(32, 64);
if (crypto_auth_verify(hmac, server_ephemeral_pk, state.network_identifier) !== 0) {
return false;
}
state.server_ephemeral_pk = server_ephemeral_pk;
return true;
};
// Returns a Buffer<112 bytes> containing a valid msg3.
// Also updates state.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `client_longterm_sk`: Buffer<64 bytes> // crypto_sign_SECRETKEYBYTES
// - `client_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `client_ephemeral_sk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `server_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `server_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
//
// This function adds the following fields to `state`:
// - `shared_secret_ab`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `shared_secret_aB`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `msg3_plaintext`: Buffer<96 bytes> // crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES
module.exports.createMsg3 = state => {
const shared_secret_ab = crypto_scalarmult(state.client_ephemeral_sk, state.server_ephemeral_pk);
const shared_secret_ab_hashed = crypto_hash_sha256(shared_secret_ab);
const shared_secret_aB = crypto_scalarmult(
state.client_ephemeral_sk,
crypto_sign_ed25519_pk_to_curve25519(state.server_longterm_pk)
);
const signed = Buffer.concat([
state.network_identifier,
state.server_longterm_pk,
shared_secret_ab_hashed
]);
const inner_signature = crypto_sign_detached(signed, state.client_longterm_sk);
const msg3_plaintext = Buffer.concat([inner_signature, state.client_longterm_pk]);
const msg3_secretbox_key = crypto_hash_sha256(Buffer.concat([
state.network_identifier,
shared_secret_ab,
shared_secret_aB
]));
state.msg3_plaintext = msg3_plaintext;
state.shared_secret_ab = shared_secret_ab;
state.shared_secret_aB = shared_secret_aB;
return crypto_secretbox_easy(msg3_plaintext, zeros, msg3_secretbox_key);
};
// Returns true iff `msg: Buffer<80 bytes>` is a valid msg4 for the given state.
// Also updates state if msg was valid.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `client_longterm_sk`: Buffer<64 bytes> // crypto_sign_SECRETKEYBYTES
// - `server_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `server_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `shared_secret_ab`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `shared_secret_aB`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `msg3_plaintext`: Buffer<96 bytes> // crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES
//
// This function adds the following fields to `state`:
// - `msg4_secretbox_key_hash`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
module.exports.verifyMsg4 = (state, msg) => {
const shared_secret_Ab = crypto_scalarmult(
crypto_sign_ed25519_sk_to_curve25519(state.client_longterm_sk),
state.server_ephemeral_pk
);
const msg4_secretbox_key = crypto_hash_sha256(Buffer.concat([
state.network_identifier,
state.shared_secret_ab,
state.shared_secret_aB,
shared_secret_Ab
]));
const msg4_plaintext = crypto_secretbox_open_easy(msg, zeros, msg4_secretbox_key);
if (!msg4_plaintext) {
// Server did not correctly encrypt msg4.
return false;
}
const shared_secret_ab_hashed = crypto_hash_sha256(state.shared_secret_ab); // Same as in createMsg3().
// This is what the server must have used to obtain `msg4_plaintext`, the signature for `signed`.
const signed = Buffer.concat([
state.network_identifier,
state.msg3_plaintext,
shared_secret_ab_hashed
]);
if (!crypto_sign_verify_detached(msg4_plaintext, signed, state.server_longterm_pk)) {
// Server did not sign correctly.
return false;
}
state.msg4_secretbox_key_hash = crypto_hash_sha256(msg4_secretbox_key);
return true;
};
// Takes the state after a successful handshake and returns the outcome data.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `client_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `client_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `server_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `server_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `msg4_secretbox_key_hash`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
//
// The returned outcome object has the fields
// - `encryption_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
// - `encryption_nonce`: Buffer<24 bytes> // crypto_box_NONCEBYTES
// - `decryption_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
// - `decryption_nonce`: Buffer<24 bytes> // crypto_box_NONCEBYTES
module.exports.clientOutcome = state => {
const encryption_key = crypto_hash_sha256(Buffer.concat([
state.msg4_secretbox_key_hash,
state.server_longterm_pk
]));
// Same as `hmac` in `verifyMsg2()`.
const server_hmac = crypto_auth(state.server_ephemeral_pk, state.network_identifier);
const encryption_nonce = server_hmac.slice(0, 24);
const decryption_key = crypto_hash_sha256(Buffer.concat([
state.msg4_secretbox_key_hash,
state.client_longterm_pk
]));
// Same as `hmac` in `createMsg1()`.
const client_hmac = crypto_auth(state.client_ephemeral_pk, state.network_identifier);
const decryption_nonce = client_hmac.slice(0, 24);
return {
encryption_key,
encryption_nonce,
decryption_key,
decryption_nonce
};
};
const {
crypto_auth_verify,
crypto_auth,
crypto_scalarmult,
crypto_hash_sha256,
crypto_sign_ed25519_sk_to_curve25519,
crypto_sign_ed25519_pk_to_curve25519,
crypto_secretbox_open_easy,
crypto_sign_verify_detached,
crypto_sign_detached,
crypto_secretbox_easy
} = require('chloride');
/*
* Implementation of the crypto the server needs to perform.
*
* Note that the initial keys have different formats, ephemeral keys are curvified:
* - `server_longterm_sk`: crypto_sign_PUBLICKEYBYTES
* - `server_longterm_pk`: crypto_sign_SECRETKEYBYTES
* - `server_ephemeral_sk`: crypto_scalarmult_curve25519_BYTES (the result of crypto_sign_ed25519_sk_to_curve25519 on crypto_sign_SECRETKEYBYTES)
* - `server_ephemeral_pk`: crypto_scalarmult_curve25519_BYTES (the result of crypto_sign_ed25519_pk_to_curve25519 on crypto_sign_PUBLICKEYBYTES)
*/
// At some points, the protocol needs 24 zero bytes in place of a nonce.
const zeros = Buffer.alloc(24);
zeros.fill(0);
// Returns true iff `msg: Buffer<64 bytes>` is a valid msg1 for the given state.
// Also updates state if msg was valid.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
//
// After successfully validating, this adds a field to `state`:
// - `client_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
module.exports.verifyMsg1 = (state, msg) => {
const hmac = msg.slice(0, 32);
const client_ephemeral_pk = msg.slice(32, 64);
if (crypto_auth_verify(hmac, client_ephemeral_pk, state.network_identifier) !== 0) {
return false;
}
state.client_ephemeral_pk = client_ephemeral_pk;
return true;
};
// Returns a Buffer<64 bytes> containing a valid msg2.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `server_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
module.exports.createMsg2 = state => {
const hmac = crypto_auth(state.server_ephemeral_pk, state.network_identifier);
return Buffer.concat([hmac, state.server_ephemeral_pk]);
};
// Returns true iff `msg: Buffer<112 bytes>` is a valid msg3 for the given state.
// Also updates state.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `server_longterm_sk`: Buffer<64 bytes> // crypto_sign_SECRETKEYBYTES
// - `server_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `server_ephemeral_sk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `client_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
//
// This function adds the following fields to `state`:
// - `client_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `shared_secret_ab`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `msg3_plaintext`: Buffer<96 bytes> // crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES
// - `msg4_secretbox_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
module.exports.verifyMsg3 = (state, msg) => {
const shared_secret_ab = crypto_scalarmult(state.server_ephemeral_sk, state.client_ephemeral_pk);
const shared_secret_ab_hashed = crypto_hash_sha256(shared_secret_ab);
const shared_secret_aB = crypto_scalarmult(
crypto_sign_ed25519_sk_to_curve25519(state.server_longterm_sk),
state.client_ephemeral_pk
);
const msg3_secretbox_key = crypto_hash_sha256(Buffer.concat([
state.network_identifier,
shared_secret_ab,
shared_secret_aB
]));
const msg3_plaintext = crypto_secretbox_open_easy(msg, zeros, msg3_secretbox_key);
if (!msg3_plaintext) {
// Could not open the box.
return false;
}
const inner_signature = msg3_plaintext.slice(0, 64);
const client_longterm_pk = msg3_plaintext.slice(64, 96);
// This is what the client must have used to obtain `inner_signature`.
const signed = Buffer.concat([
state.network_identifier,
state.server_longterm_pk,
shared_secret_ab_hashed
]);
if (!crypto_sign_verify_detached(inner_signature, signed, client_longterm_pk)) {
// Client did not sign correctly.
return false;
}
const shared_secret_Ab = crypto_scalarmult(
state.server_ephemeral_sk,
crypto_sign_ed25519_pk_to_curve25519(client_longterm_pk)
);
const msg4_secretbox_key = crypto_hash_sha256(Buffer.concat([
state.network_identifier,
shared_secret_ab,
shared_secret_aB,
shared_secret_Ab
]));
state.client_longterm_pk = client_longterm_pk;
state.msg3_plaintext = msg3_plaintext;
state.shared_secret_ab = shared_secret_ab;
state.msg4_secretbox_key = msg4_secretbox_key;
return true;
};
// Returns a Buffer<80 bytes> containing a valid msg4.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `server_longterm_sk`: Buffer<64 bytes> // crypto_sign_SECRETKEYBYTES
// - `shared_secret_ab`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `msg3_plaintext`: Buffer<96 bytes> // crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES
// - `msg4_secretbox_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
module.exports.createMsg4 = state => {
const shared_secret_ab_hashed = crypto_hash_sha256(state.shared_secret_ab); // Same as in verifyMsg3().
// The signature of this is the plaintext for msg4.
const signed = Buffer.concat([
state.network_identifier,
state.msg3_plaintext,
shared_secret_ab_hashed
]);
const msg4_plaintext = crypto_sign_detached(signed, state.server_longterm_sk);
return crypto_secretbox_easy(msg4_plaintext, zeros, state.msg4_secretbox_key);
};
// Takes the state after a successful handshake and returns the outcome data.
//
// `state` is an object with (at least) the fields
// - `network_identifier`: Buffer<32 bytes> // shs_NETWORKIDENTIFIERBYTES
// - `server_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `server_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `client_longterm_pk`: Buffer<32 bytes> // crypto_sign_PUBLICKEYBYTES
// - `client_ephemeral_pk`: Buffer<32 bytes> // crypto_scalarmult_curve25519_BYTES
// - `msg4_secretbox_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
//
// The returned outcome object has the fields
// - `encryption_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
// - `encryption_nonce`: Buffer<24 bytes> // crypto_box_NONCEBYTES
// - `decryption_key`: Buffer<32 bytes> // crypto_hash_sha256_BYTES
// - `decryption_nonce`: Buffer<24 bytes> // crypto_box_NONCEBYTES
module.exports.serverOutcome = state => {
const msg4_secretbox_key_hash = crypto_hash_sha256(state.msg4_secretbox_key);
const encryption_key = crypto_hash_sha256(Buffer.concat([
msg4_secretbox_key_hash,
state.client_longterm_pk
]));
// Same as `hmac` in `verifyMsg1()`.
const client_hmac = crypto_auth(state.client_ephemeral_pk, state.network_identifier);
const encryption_nonce = client_hmac.slice(0, 24);
const decryption_key = crypto_hash_sha256(Buffer.concat([
msg4_secretbox_key_hash,
state.server_longterm_pk
]));
// Same as `hmac` in `createMsg2()`.
const server_hmac = crypto_auth(state.server_ephemeral_pk, state.network_identifier);
const decryption_nonce = server_hmac.slice(0, 24);
return {
encryption_key,
encryption_nonce,
decryption_key,
decryption_nonce
};
};
// This only tests a successful handshake. The real module will also test that malformed messages are detected.
const assert = require('assert');
const {createMsg1, verifyMsg2, createMsg3, verifyMsg4, clientOutcome} = require('./crypto-client');
const {verifyMsg1, createMsg2, verifyMsg3, createMsg4, serverOutcome} = require('./crypto-server');
const network_identifier = Buffer.from([111, 97, 159, 86, 19, 13, 53, 115, 66, 209, 32, 84, 255, 140, 143, 85, 157, 74, 32, 154, 156, 90, 29, 185, 141, 19, 184, 255, 104, 107, 124, 198]);
const server_longterm_pk = Buffer.from([42, 190, 113, 153, 16, 248, 187, 195, 163, 201, 187, 204, 86, 238, 66, 151, 52, 115, 160, 4, 244, 1, 12, 76, 170, 129, 66, 12, 202, 54, 1, 70]);
const clientState = {
client_longterm_sk: Buffer.from([243, 168, 6, 50, 44, 78, 192, 183, 210, 241, 189, 36, 183, 154, 132, 119, 115, 84, 47, 151, 32, 32, 26, 237, 64, 180, 69, 20, 95, 133, 92, 176, 225, 162, 73, 136, 73, 119, 94, 84, 208, 102, 233, 120, 23, 46, 225, 245, 198, 79, 176, 0, 151, 208, 70, 146, 111, 23, 94, 101, 25, 192, 30, 35]),
client_longterm_pk: Buffer.from([225, 162, 73, 136, 73, 119, 94, 84, 208, 102, 233, 120, 23, 46, 225, 245, 198, 79, 176, 0, 151, 208, 70, 146, 111, 23, 94, 101, 25, 192, 30, 35]),
client_ephemeral_sk: Buffer.from([80, 169, 55, 157, 134, 142, 219, 152, 125, 240, 174, 209, 225, 109, 46, 188, 97, 224, 193, 187, 198, 58, 226, 193, 24, 235, 213, 214, 49, 55, 213, 104]),
client_ephemeral_pk: Buffer.from([79, 79, 77, 238, 254, 215, 129, 197, 235, 41, 185, 208, 47, 32, 146, 37, 255, 237, 208, 215, 182, 92, 201, 106, 85, 86, 157, 41, 53, 165, 177, 32]),
server_longterm_pk,
network_identifier
};
const serverState = {
server_longterm_sk: Buffer.from([118, 98, 17, 77, 86, 116, 58, 146, 99, 84, 198, 164, 35, 220, 73, 213, 246, 224, 242, 230, 175, 116, 71, 218, 56, 37, 212, 66, 163, 14, 74, 209, 42, 190, 113, 153, 16, 248, 187, 195, 163, 201, 187, 204, 86, 238, 66, 151, 52, 115, 160, 4, 244, 1, 12, 76, 170, 129, 66, 12, 202, 54, 1, 70]),
server_longterm_pk,
server_ephemeral_sk: Buffer.from([176, 248, 210, 185, 226, 76, 162, 153, 239, 144, 57, 206, 218, 97, 2, 215, 155, 5, 223, 189, 22, 28, 137, 85, 228, 233, 93, 79, 217, 203, 63, 125]),
server_ephemeral_pk: Buffer.from([166, 12, 63, 218, 235, 136, 61, 99, 232, 142, 165, 147, 88, 93, 79, 177, 23, 148, 129, 57, 179, 24, 192, 174, 90, 62, 40, 83, 51, 9, 97, 82]),
network_identifier
};
const msg1 = createMsg1(clientState);
assert.deepStrictEqual(
msg1,
Buffer.from([211, 6, 20, 155, 178, 209, 30, 107, 1, 3, 140, 242, 73, 101, 116, 234, 249, 127, 131, 227, 142, 66, 240, 195, 13, 50, 38, 96, 7, 208, 124, 180, 79, 79, 77, 238, 254, 215, 129, 197, 235, 41, 185, 208, 47, 32, 146, 37, 255, 237, 208, 215, 182, 92, 201, 106, 85, 86, 157, 41, 53, 165, 177, 32]),
'createMsg1 failed'
);
assert(verifyMsg1(serverState, msg1), 'verifyMsg1 failed');
const msg2 = createMsg2(serverState);
assert.deepStrictEqual(
msg2,
Buffer.from([44, 140, 79, 227, 23, 153, 202, 203, 81, 40, 114, 59, 56, 167, 63, 166, 201, 9, 50, 152, 0, 255, 226, 147, 22, 43, 84, 99, 107, 198, 198, 219, 166, 12, 63, 218, 235, 136, 61, 99, 232, 142, 165, 147, 88, 93, 79, 177, 23, 148, 129, 57, 179, 24, 192, 174, 90, 62, 40, 83, 51, 9, 97, 82]),
'createMsg2 failed'
);
assert(verifyMsg2(clientState, msg2), 'verifyMsg2 failed');
const msg3 = createMsg3(clientState);
assert.deepStrictEqual(
msg3,
Buffer.from([80, 34, 24, 195, 46, 211, 235, 66, 91, 89, 65, 98, 137, 26, 86, 197, 32, 4, 153, 142, 160, 18, 56, 180, 12, 171, 127, 38, 44, 53, 74, 64, 55, 188, 22, 25, 161, 25, 7, 243, 200, 196, 145, 249, 207, 211, 88, 178, 0, 206, 173, 234, 188, 20, 251, 240, 199, 169, 94, 180, 212, 32, 150, 226, 138, 44, 141, 235, 33, 152, 91, 215, 31, 126, 48, 48, 220, 239, 97, 225, 103, 79, 190, 56, 227, 103, 142, 195, 124, 10, 21, 76, 66, 11, 194, 11, 220, 15, 163, 66, 138, 232, 228, 12, 130, 172, 4, 137, 52, 159, 64, 98]),
'createMsg3 failed'
);
assert(verifyMsg3(serverState, msg3), 'verifyMsg3 failed');
const msg4 = createMsg4(serverState);
assert.deepStrictEqual(
msg4,
Buffer.from([72, 114, 92, 105, 109, 48, 17, 14, 25, 150, 242, 50, 148, 70, 49, 25, 222, 254, 255, 124, 194, 144, 84, 114, 190, 148, 252, 189, 159, 132, 157, 173, 92, 14, 247, 198, 87, 232, 141, 83, 84, 79, 226, 43, 194, 95, 14, 8, 138, 233, 96, 40, 126, 153, 205, 36, 95, 203, 200, 202, 221, 118, 126, 99, 47, 216, 209, 219, 3, 133, 240, 216, 166, 182, 182, 226, 215, 116, 177, 66]),
'createMsg4 failed'
);
assert(verifyMsg4(clientState, msg4), 'verifyMsg4 failed');
assert.deepStrictEqual(
clientOutcome(clientState),
{
encryption_key: Buffer.from([162, 29, 153, 150, 123, 225, 10, 173, 175, 201, 160, 34, 190, 179, 158, 14, 176, 105, 232, 238, 97, 66, 133, 194, 250, 148, 199, 7, 34, 157, 174, 24]),
encryption_nonce: Buffer.from([44, 140, 79, 227, 23, 153, 202, 203, 81, 40, 114, 59, 56, 167, 63, 166, 201, 9, 50, 152, 0, 255, 226, 147]),
decryption_key: Buffer.from([125, 136, 153, 7, 109, 241, 239, 84, 228, 176, 141, 23, 58, 129, 90, 228, 188, 93, 191, 224, 209, 67, 147, 187, 45, 204, 178, 17, 77, 225, 117, 98]),
decryption_nonce: Buffer.from([211, 6, 20, 155, 178, 209, 30, 107, 1, 3, 140, 242, 73, 101, 116, 234, 249, 127, 131, 227, 142, 66, 240, 195])
},
'clientOutcome failed'
);
assert.deepStrictEqual(
serverOutcome(serverState),
{
encryption_key: Buffer.from([125, 136, 153, 7, 109, 241, 239, 84, 228, 176, 141, 23, 58, 129, 90, 228, 188, 93, 191, 224, 209, 67, 147, 187, 45, 204, 178, 17, 77, 225, 117, 98]),
encryption_nonce: Buffer.from([211, 6, 20, 155, 178, 209, 30, 107, 1, 3, 140, 242, 73, 101, 116, 234, 249, 127, 131, 227, 142, 66, 240, 195]),
decryption_key: Buffer.from([162, 29, 153, 150, 123, 225, 10, 173, 175, 201, 160, 34, 190, 179, 158, 14, 176, 105, 232, 238, 97, 66, 133, 194, 250, 148, 199, 7, 34, 157, 174, 24]),
decryption_nonce: Buffer.from([44, 140, 79, 227, 23, 153, 202, 203, 81, 40, 114, 59, 56, 167, 63, 166, 201, 9, 50, 152, 0, 255, 226, 147])
},
'serverOutcome failed'
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment