Last active
October 31, 2017 19:08
-
-
Save AljoschaMeyer/bdcac0377fdef904119a52c41bd50871 to your computer and use it in GitHub Desktop.
js implementation of secret-handshake, with a focus on readability
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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