Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
matrix-org
Olm
Commits
09d8e84c
Commit
09d8e84c
authored
Feb 26, 2015
by
Mark Haines
Browse files
Implement the axlotl ratchet
parent
186df912
Changes
7
Show whitespace changes
Inline
Side-by-side
include/axolotl/axolotl.hh
View file @
09d8e84c
#include "axolo
l
t/crypto.hh"
#include "axolo
l
t/list.hh"
#include "axolot
l
/crypto.hh"
#include "axolot
l
/list.hh"
namespace
axolotl
{
...
...
@@ -52,7 +52,10 @@ enum struct ErrorCode {
static
std
::
size_t
const
MAX_RECEIVER_CHAINS
=
5
;
static
std
::
size_t
const
MAX_SKIPPED_MESSAGE_KEYS
=
40
;
struct
KdfInfo
{
std
::
uint8_t
const
*
root_info
;
std
::
size_t
root_info_length
;
std
::
uint8_t
const
*
ratchet_info
;
std
::
size_t
ratchet_info_length
;
std
::
uint8_t
const
*
message_info
;
...
...
@@ -61,15 +64,30 @@ struct KdfInfo {
struct
Session
{
Session
(
KdfInfo
const
&
kdf_info
);
/** A pair of string to feed into the KDF identifing the application */
KdfInfo
kdf_info
;
/** The last error that happened encypting or decrypting a message */
ErrorCode
last_error
;
SharedKey
root_key
;
List
<
SenderChain
,
1
>
sender_chain
;
List
<
ReceiverChain
,
MAX_RECEIVER_CHAINS
>
rec
i
ever_chains
;
List
<
ReceiverChain
,
MAX_RECEIVER_CHAINS
>
rece
i
ver_chains
;
List
<
SkippedMessageKey
,
MAX_SKIPPED_MESSAGE_KEYS
>
skipped_message_keys
;
void
initialise_as_bob
(
std
::
uint8_t
const
*
shared_secret
,
std
::
size_t
shared_secret_length
,
Curve25519PublicKey
const
&
their_ratchet_key
);
void
initialise_as_alice
(
std
::
uint8_t
const
*
shared_secret
,
std
::
size_t
shared_secret_length
,
Curve25519KeyPair
const
&
our_ratchet_key
);
std
::
size_t
encrypt_max_output_length
(
std
::
size_t
plaintext_length
);
...
...
include/axolotl/crypto.hh
View file @
09d8e84c
...
...
@@ -15,8 +15,9 @@ struct Curve25519KeyPair : public Curve25519PublicKey {
};
Curve25519KeyPair
generate_key
(
std
::
uint8_t
const
*
random_32_bytes
void
generate_key
(
std
::
uint8_t
const
*
random_32_bytes
,
Curve25519KeyPair
&
key_pair
);
...
...
include/axolotl/list.hh
View file @
09d8e84c
...
...
@@ -60,6 +60,11 @@ public:
return
pos
;
}
/**
* Make space for an item in the list at the start of the list
*/
T
*
insert
()
{
return
insert
(
begin
());
}
/**
* Insert an item into the list at a given position.
* If inserting the item makes the list longer than max_size then
...
...
src/axolotl.cpp
View file @
09d8e84c
#include "axolotl/axolotl.hh"
#include "axolotl/message.hh"
#include <cstring>
namespace
{
std
::
uint8_t
PROTOCOL_VERSION
=
3
;
std
::
size_t
MAC_LENGTH
=
8
;
std
::
size_t
KEY_LENGTH
=
Curve25519PublicKey
::
L
ength
;
std
::
size_t
KEY_LENGTH
=
axolotl
::
Curve25519PublicKey
::
L
ENGTH
;
std
::
uint8_t
MESSAGE_KEY_SEED
[
1
]
=
{
0x01
};
std
::
uint8_t
CHAIN_KEY_SEED
[
1
]
=
{
0x02
};
std
::
size_t
MAX_MESSAGE_GAP
=
2000
;
template
<
typename
T
>
void
unset
(
T
&
value
)
{
std
::
memset
(
&
value
,
0
,
sizeof
(
T
));
}
void
create_chain_key
(
axolotl
::
SharedKey
const
&
root_key
,
Curve25519KeyPair
const
&
our_key
,
Curve25519PublicKey
const
&
their_key
,
std
::
uint8_t
const
*
info
,
std
::
size_t
info_length
,
SharedSecret
&
new_root_key
,
ChainKey
&
new_chain_key
axolotl
::
Curve25519KeyPair
const
&
our_key
,
axolotl
::
Curve25519PublicKey
const
&
their_key
,
axolotl
::
KdfInfo
const
&
info
,
axolotl
::
SharedKey
&
new_root_key
,
axolotl
::
ChainKey
&
new_chain_key
)
{
axolotl
::
Shared
Secret
secret
;
axolotl
::
Shared
Key
secret
;
axolotl
::
curve25519_shared_secret
(
our_key
,
their_key
,
secret
);
std
::
uint8_t
derived_secrets
[
64
];
axolotl
::
hkdf_sha256
(
secret
,
sizeof
(
secret
),
root_key
,
sizeof
(
root_key
),
info
,
info_length
,
info
.
ratchet_info
,
info
.
ratchet_
info_length
,
derived_secrets
,
sizeof
(
derived_secrets
)
);
std
::
memcpy
(
new_root_key
,
derived_secrets
,
32
);
std
::
memcpy
(
new_chain_key
.
key
,
derived_secrets
+
32
,
32
);
new_chain_key
.
index
=
0
;
std
::
memset
(
derived_secrets
,
0
,
sizeof
(
derived_secrets
);
std
::
mem
set
(
secret
,
0
,
sizeof
(
secret
)
);
unset
(
derived_secrets
);
un
set
(
secret
);
}
void
advance_chain_key
(
ChainKey
const
&
chain_key
,
ChainKey
&
new_chain_key
,
axolotl
::
ChainKey
const
&
chain_key
,
axolotl
::
ChainKey
&
new_chain_key
)
{
axolotl
::
hmac_sha256
(
chain_key
.
key
,
sizeof
(
chain_key
.
key
),
...
...
@@ -49,11 +59,11 @@ void advance_chain_key(
void
create_message_keys
(
ChainKey
const
&
chain_key
,
std
::
uint8_t
const
*
info
,
std
::
size_t
info_length
,
MessageKey
&
message_key
axolotl
::
ChainKey
const
&
chain_key
,
axolotl
::
KdfInfo
const
&
info
,
axolotl
::
MessageKey
&
message_key
)
{
axolotl
::
Shared
Secret
secret
;
axolotl
::
Shared
Key
secret
;
axolotl
::
hmac_sha256
(
chain_key
.
key
,
sizeof
(
chain_key
.
key
),
MESSAGE_KEY_SEED
,
sizeof
(
MESSAGE_KEY_SEED
),
...
...
@@ -62,45 +72,43 @@ void create_message_keys(
std
::
uint8_t
derived_secrets
[
80
];
axolotl
::
hkdf_sha256
(
secret
,
sizeof
(
secret
),
root_key
,
sizeof
(
root_key
)
,
info
,
info_length
,
NULL
,
0
,
info
.
message_info
,
info
.
message_
info_length
,
derived_secrets
,
sizeof
(
derived_secrets
)
);
std
::
memcpy
(
message_key
.
cipher_key
,
derived_secrets
,
32
);
std
::
memcpy
(
message_key
.
cipher_key
.
key
,
derived_secrets
,
32
);
std
::
memcpy
(
message_key
.
mac_key
,
derived_secrets
+
32
,
32
);
std
::
memcpy
(
message_key
.
iv
,
derived_secrets
+
64
,
16
);
std
::
memcpy
(
message_key
.
iv
.
iv
,
derived_secrets
+
64
,
16
);
message_key
.
index
=
chain_key
.
index
;
std
::
memset
(
derived_secrets
,
0
,
sizeof
(
derived_secrets
);
std
::
mem
set
(
secret
,
0
,
sizeof
(
secret
)
);
unset
(
derived_secrets
);
un
set
(
secret
);
}
bool
verify_mac
(
MessageKey
const
&
message_key
,
axolotl
::
MessageKey
const
&
message_key
,
std
::
uint8_t
const
*
input
,
axolotl
::
MessageReader
const
&
reader
)
{
std
::
uint8_t
mac
[
HMAC_SHA256_OUTPUT_LENGTH
];
std
::
uint8_t
mac
[
axolotl
::
HMAC_SHA256_OUTPUT_LENGTH
];
axolotl
::
hmac_sha256
(
key
s
.
mac_key
,
sizeof
(
key
s
.
mac_key
),
ciphertex
t
,
reader
.
body_length
,
message_
key
.
mac_key
,
sizeof
(
message_
key
.
mac_key
),
inpu
t
,
reader
.
body_length
,
mac
);
bool
result
=
std
::
memcmp
(
mac
,
reader
.
mac
,
MAC_LENGTH
)
==
0
;
std
::
mem
set
(
&
mac
,
0
,
HMAC_SHA256_OUTPUT_LENGTH
);
un
set
(
mac
);
return
result
;
}
bool
verify_mac_for_existing_chain
(
axolotl
::
Session
const
&
session
,
axolotl
::
Receiver
Chain
const
&
chain
,
axolotl
::
Chain
Key
const
&
chain
,
std
::
uint8_t
const
*
input
,
axolotl
::
MessageReader
const
&
reader
)
{
ReceiverChain
new_chain
=
chain
;
if
(
reader
.
counter
<
chain
.
index
)
{
return
false
;
}
...
...
@@ -110,18 +118,17 @@ bool verify_mac_for_existing_chain(
return
false
;
}
axolotl
::
ChainKey
new_chain
=
chain
;
while
(
new_chain
.
index
<
reader
.
counter
)
{
advance_chain_key
(
new_chain
,
new_chain
);
}
MessageKey
message_key
;
create_message_keys
(
new_chain_key
,
sender
.
message_info
,
sender
.
message_info_length
,
message_key
);
axolotl
::
MessageKey
message_key
;
create_message_keys
(
new_chain
,
session
.
kdf_info
,
message_key
);
bool
result
=
verify_mac
(
message_key
,
input
,
reader
);
std
::
memset
(
&
new_chain
,
0
,
sizeof
(
new_chain
.
ratchet_key
);
unset
(
new_chain
);
return
result
;
}
...
...
@@ -131,8 +138,8 @@ bool verify_mac_for_new_chain(
std
::
uint8_t
const
*
input
,
axolotl
::
MessageReader
const
&
reader
)
{
SharedSecret
new_root_key
;
ReceiverChain
new_chain
;
axolotl
::
SharedKey
new_root_key
;
axolotl
::
ReceiverChain
new_chain
;
/* They shouldn't move to a new chain until we've sent them a message
* acknowledging the last one */
...
...
@@ -144,30 +151,78 @@ bool verify_mac_for_new_chain(
if
(
reader
.
counter
>
MAX_MESSAGE_GAP
)
{
return
false
;
}
std
::
memcpy
(
new_chain
.
ratchet_key
,
reader
.
ratchet_key
,
KEY_LENGTH
);
std
::
memcpy
(
new_chain
.
ratchet_key
.
public_key
,
reader
.
ratchet_key
,
KEY_LENGTH
);
create_chain_key
(
root_key
,
sender_chain
[
0
].
ratchet_key
,
new_chain
.
ratchet_key
,
session
.
kdf_info
.
ratchet_
info
,
session
.
kdf_info
.
ratchet_info_length
,
new_root_key
,
new_chain
session
.
root_key
,
session
.
sender_chain
[
0
].
ratchet_key
,
new_chain
.
ratchet_
key
,
session
.
kdf_info
,
new_root_key
,
new_chain
.
chain_key
);
bool
result
=
verify_mac_for_existing_chain
(
session
,
new_chain
,
input
,
reader
session
,
new_chain
.
chain_key
,
input
,
reader
);
std
::
memset
(
&
new_root_key
,
0
,
sizeof
(
new_root_key
)
)
;
std
::
memset
(
&
new_chain
,
0
,
sizeof
(
new_chain
.
ratchet_key
);
unset
(
new_root_key
);
unset
(
new_chain
);
return
result
;
}
}
// namespace
axolotl
::
Session
::
Session
(
axolotl
::
KdfInfo
const
&
kdf_info
)
:
kdf_info
(
kdf_info
),
last_error
(
axolotl
::
ErrorCode
::
SUCCESS
)
{
}
void
axolotl
::
Session
::
initialise_as_bob
(
std
::
uint8_t
const
*
shared_secret
,
std
::
size_t
shared_secret_length
,
axolotl
::
Curve25519PublicKey
const
&
their_ratchet_key
)
{
std
::
uint8_t
derived_secrets
[
64
];
axolotl
::
hkdf_sha256
(
shared_secret
,
shared_secret_length
,
NULL
,
0
,
kdf_info
.
root_info
,
kdf_info
.
root_info_length
,
derived_secrets
,
sizeof
(
derived_secrets
)
);
receiver_chains
.
insert
();
std
::
memcpy
(
root_key
,
derived_secrets
,
32
);
std
::
memcpy
(
receiver_chains
[
0
].
chain_key
.
key
,
derived_secrets
+
32
,
32
);
receiver_chains
[
0
].
ratchet_key
=
their_ratchet_key
;
unset
(
derived_secrets
);
}
void
axolotl
::
Session
::
initialise_as_alice
(
std
::
uint8_t
const
*
shared_secret
,
std
::
size_t
shared_secret_length
,
axolotl
::
Curve25519KeyPair
const
&
our_ratchet_key
)
{
std
::
uint8_t
derived_secrets
[
64
];
axolotl
::
hkdf_sha256
(
shared_secret
,
shared_secret_length
,
NULL
,
0
,
kdf_info
.
root_info
,
kdf_info
.
root_info_length
,
derived_secrets
,
sizeof
(
derived_secrets
)
);
sender_chain
.
insert
();
std
::
memcpy
(
root_key
,
derived_secrets
,
32
);
std
::
memcpy
(
sender_chain
[
0
].
chain_key
.
key
,
derived_secrets
+
32
,
32
);
sender_chain
[
0
].
ratchet_key
=
our_ratchet_key
;
unset
(
derived_secrets
);
}
std
::
size_t
axolotl
::
Session
::
encrypt_max_output_length
(
std
::
size_t
plaintext_length
)
{
std
::
size_t
key_length
=
1
+
varstring_length
(
Curve25519PublicKey
::
Length
);
std
::
size_t
counter
=
sender_chain
.
empty
()
?
0
:
sender_chain
[
0
].
index
;
std
::
size_t
counter
=
0
;
if
(
!
sender_chain
.
empty
())
{
counter
=
sender_chain
[
0
].
chain_key
.
index
;
}
std
::
size_t
padded
=
axolotl
::
aes_encrypt_cbc_length
(
plaintext_length
);
return
axolotl
::
encode_message_length
(
counter
,
KEY_LENGTH
,
padded
,
MAC_LENGTH
...
...
@@ -176,7 +231,7 @@ std::size_t axolotl::Session::encrypt_max_output_length(
std
::
size_t
axolotl
::
Session
::
encrypt_random_length
()
{
return
sender_chain
.
size
()
?
Curve25519PublicKey
::
Length
:
0
;
return
sender_chain
.
empty
()
?
KEY_LENGTH
:
0
;
}
...
...
@@ -189,29 +244,36 @@ std::size_t axolotl::Session::encrypt(
last_error
=
axolotl
::
ErrorCode
::
NOT_ENOUGH_RANDOM
;
return
std
::
size_t
(
-
1
);
}
if
(
max_output_length
<
encrypt_max_output_length
())
{
if
(
max_output_length
<
encrypt_max_output_length
(
plaintext_length
))
{
last_error
=
axolotl
::
ErrorCode
::
OUTPUT_BUFFER_TOO_SMALL
;
return
std
::
size_t
(
-
1
);
}
if
(
sender_chain
.
empty
())
{
/** create sender chain */
sender_chain
.
insert
();
axolotl
::
generate_key
(
random
,
sender_chain
[
0
].
ratchet_key
);
create_chain_key
(
root_key
,
sender_chain
[
0
].
ratchet_key
,
receiver_chains
[
0
].
ratchet_key
,
kdf_info
,
root_key
,
sender_chain
[
0
].
chain_key
);
}
MessageKey
keys
;
/** create message keys and advance chain */
create_message_keys
(
sender_chain
[
0
].
chain_key
,
kdf_info
,
keys
);
advance_chain_key
(
sender_chain
[
0
].
chain_key
,
sender_chain
[
0
].
chain_key
);
std
::
size_t
padded
=
axolotl
::
aes_encrypt_cbc_length
(
plaintext_length
);
std
::
size_t
key_length
=
Curve25519PublicKey
::
Length
;
std
::
uint32_t
counter
=
keys
.
index
;
const
Curve25519PublicKey
&
ratchet_key
=
sender_chain
[
0
].
ratchet_key
;
axolotl
::
MessageWriter
writer
(
axolotl
::
encode_message
(
PROTOCOL_VERSION
,
counter
,
key_length
,
padded
,
cipher_tex
t
PROTOCOL_VERSION
,
counter
,
KEY_LENGTH
,
padded
,
outpu
t
));
std
::
memcpy
(
writer
.
ratchet_key
,
ratchet_key
.
public_key
,
key_length
);
std
::
memcpy
(
writer
.
ratchet_key
,
ratchet_key
.
public_key
,
KEY_LENGTH
);
axolotl
::
aes_encrypt_cbc
(
keys
.
cipher_key
,
keys
.
iv
,
...
...
@@ -219,19 +281,20 @@ std::size_t axolotl::Session::encrypt(
writer
.
ciphertext
);
std
::
uint8_t
mac
[
HMAC_SHA256_OUTPUT_LENGTH
];
std
::
uint8_t
mac
[
axolotl
::
HMAC_SHA256_OUTPUT_LENGTH
];
axolotl
::
hmac_sha256
(
keys
.
mac_key
,
sizeof
(
keys
.
mac_key
),
ciphertex
t
,
writer
.
body_length
,
outpu
t
,
writer
.
body_length
,
mac
);
std
::
memcpy
(
writer
.
mac
,
mac
,
MAC_LENGTH
);
unset
(
keys
);
return
writer
.
body_length
+
MAC_LENGTH
;
}
std
::
size_t
decrypt_max_plaintext_length
(
std
::
size_t
axolotl
::
Session
::
decrypt_max_plaintext_length
(
std
::
size_t
input_length
)
{
return
input_length
;
...
...
@@ -256,8 +319,7 @@ std::size_t axolotl::Session::decrypt(
return
std
::
size_t
(
-
1
);
}
if
(
reader
.
body_length
==
0
||
reader
.
ratchet_key_length
!=
Curve25519PublicKey
::
Length
)
{
if
(
reader
.
body_length
==
0
||
reader
.
ratchet_key_length
!=
KEY_LENGTH
)
{
last_error
=
axolotl
::
ErrorCode
::
BAD_MESSAGE_FORMAT
;
return
std
::
size_t
(
-
1
);
}
...
...
@@ -265,7 +327,8 @@ std::size_t axolotl::Session::decrypt(
ReceiverChain
*
chain
=
NULL
;
for
(
axolotl
::
ReceiverChain
&
receiver_chain
:
receiver_chains
)
{
if
(
0
==
std
::
memcmp
(
receiver_chain
.
ratchet_key
,
reader
.
ratchet_key
,
KEY_LENGTH
receiver_chain
.
ratchet_key
.
public_key
,
reader
.
ratchet_key
,
KEY_LENGTH
))
{
chain
=
&
receiver_chain
;
break
;
...
...
@@ -278,15 +341,16 @@ std::size_t axolotl::Session::decrypt(
return
std
::
size_t
(
-
1
);
}
}
else
{
if
(
chain
->
index
>
reader
.
counter
)
{
if
(
chain
->
chain_key
.
index
>
reader
.
counter
)
{
/* Chain already advanced beyond the key for this message
* Check if the message keys are in the skipped key list. */
for
(
const
axolotl
::
SkippedMessageKey
&
skipped
:
skipped_message_keys
)
{
for
(
axolotl
::
SkippedMessageKey
&
skipped
:
skipped_message_keys
)
{
if
(
reader
.
counter
==
skipped
.
message_key
.
index
&&
0
==
std
::
memcmp
(
skipped
.
ratchet_key
,
reader
.
ratchet_key
,
KEY_LENGTH
))
{
skipped
.
ratchet_key
.
public_key
,
reader
.
ratchet_key
,
KEY_LENGTH
)
)
{
/* Found the key for this message. Check the MAC. */
if
(
!
verify_mac
(
skipped
.
message_key
,
input
,
reader
))
{
last_error
=
axolotl
::
ErrorCode
::
BAD_MESSAGE_MAC
;
...
...
@@ -307,6 +371,7 @@ std::size_t axolotl::Session::decrypt(
/* Remove the key from the skipped keys now that we've
* decoded the message it corresponds to. */
unset
(
skipped
);
skipped_message_keys
.
erase
(
&
skipped
);
return
result
;
}
...
...
@@ -314,18 +379,54 @@ std::size_t axolotl::Session::decrypt(
/* No matching keys for the message, fail with bad mac */
last_error
=
axolotl
::
ErrorCode
::
BAD_MESSAGE_MAC
;
return
std
::
size_t
(
-
1
);
}
else
if
(
!
verify_mac_for_existing_chain
(
*
chain
,
input
,
reader
))
{
}
else
if
(
!
verify_mac_for_existing_chain
(
*
this
,
chain
->
chain_key
,
input
,
reader
))
{
last_error
=
axolotl
::
ErrorCode
::
BAD_MESSAGE_MAC
;
return
std
::
size_t
(
-
1
);
}
}
if
(
!
chain
)
{
/* They have started using a new empheral ratchet key.
* We need to derive a new set of chain keys.
* We can discard our previous empheral ratchet key.
* We will generate a new key when we send the next message. */
chain
=
receiver_chains
.
insert
();
std
::
memcpy
(
chain
->
ratchet_key
.
public_key
,
reader
.
ratchet_key
,
KEY_LENGTH
);
create_chain_key
(
root_key
,
sender_chain
[
0
].
ratchet_key
,
chain
->
ratchet_key
,
kdf_info
,
root_key
,
chain
->
chain_key
);
unset
(
sender_chain
[
0
]);
sender_chain
.
erase
(
sender_chain
.
begin
());
}
while
(
chain
->
chain_key
.
index
<
reader
.
counter
)
{
axolotl
::
SkippedMessageKey
&
key
=
*
skipped_message_keys
.
insert
();
create_message_keys
(
chain
->
chain_key
,
kdf_info
,
key
.
message_key
);
key
.
ratchet_key
=
chain
->
ratchet_key
;
advance_chain_key
(
chain
->
chain_key
,
chain
->
chain_key
);
}
axolotl
::
MessageKey
message_key
;
create_message_keys
(
chain
->
chain_key
,
kdf_info
,
message_key
);
std
::
size_t
result
=
axolotl
::
aes_decrypt_cbc
(
message_key
.
cipher_key
,
message_key
.
iv
,
reader
.
ciphertext
,
reader
.
ciphertext_length
,
plaintext
);
unset
(
message_key
);
advance_chain_key
(
chain
->
chain_key
,
chain
->
chain_key
);
if
(
result
==
std
::
size_t
(
-
1
))
{
last_error
=
axolotl
::
ErrorCode
::
BAD_MESSAGE_MAC
;
return
std
::
size_t
(
-
1
);
}
else
{
return
result
;
}
}
src/crypto.cpp
View file @
09d8e84c
...
...
@@ -23,6 +23,7 @@ static const std::size_t SHA256_HASH_LENGTH = 32;
static
const
std
::
size_t
SHA256_BLOCK_LENGTH
=
64
;
static
const
std
::
uint8_t
HKDF_DEFAULT_SALT
[
32
]
=
{};
template
<
std
::
size_t
block_size
>
inline
static
void
xor_block
(
std
::
uint8_t
*
block
,
...
...
@@ -86,15 +87,14 @@ inline void hmac_sha256_final(
}
// namespace
axolotl
::
Curve25519KeyPair
axolotl
::
generate_key
(
std
::
uint8_t
const
*
random_32_bytes
void
axolotl
::
generate_key
(
std
::
uint8_t
const
*
random_32_bytes
,
axolotl
::
Curve25519KeyPair
&
key_pair
)
{
axolotl
::
Curve25519KeyPair
key_pair
;
std
::
memcpy
(
key_pair
.
private_key
,
random_32_bytes
,
32
);
::
curve25519_donna
(
key_pair
.
public_key
,
key_pair
.
private_key
,
CURVE25519_BASEPOINT
);
return
key_pair
;
}
...
...
test.py
0 → 100644
View file @
09d8e84c
import
subprocess
import
glob
import
os
if
not
os
.
path
.
exists
(
"build"
):
os
.
mkdir
(
"build"
)
test_files
=
glob
.
glob
(
"tests/test_*.cpp"
)
source_files
=
glob
.
glob
(
"src/*.cpp"
)
compile_args
=
"g++ -Itests/include -Iinclude -Ilib --std=c++11"
.
split
()
compile_args
+=
source_files
for
test_file
in
test_files
:
exe_file
=
"build/"
+
test_file
[:
4
]
subprocess
.
check_call
(
compile_args
+
[
test_file
,
"-o"
,
exe_file
])
subprocess
.
check_call
([
exe_file
])
tests/test_crypto.cpp
View file @
09d8e84c
...
...
@@ -44,12 +44,14 @@ std::uint8_t expected_agreement[32] = {
0x76
,
0xF0
,
0x9B
,
0x3C
,
0x1E
,
0x16
,
0x17
,
0x42
};
axolotl
::
Curve25519KeyPair
alice_pair
=
axolotl
::
generate_key
(
alice_private
);
axolotl
::
Curve25519KeyPair
alice_pair
;
axolotl
::
generate_key
(
alice_private
,
alice_pair
);
assert_equals
(
alice_private
,
alice_pair
.
private_key
,
32
);
assert_equals
(
alice_public
,
alice_pair
.
public_key
,
32
);
axolotl
::
Curve25519KeyPair
bob_pair
=
axolotl
::
generate_key
(
bob_private
);
axolotl
::
Curve25519KeyPair
bob_pair
;
axolotl
::
generate_key
(
bob_private
,
bob_pair
);
assert_equals
(
bob_private
,
bob_pair
.
private_key
,
32
);
assert_equals
(
bob_public
,
bob_pair
.
public_key
,
32
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment