Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
talla
enacl
Commits
57bb9368
Commit
57bb9368
authored
Nov 26, 2014
by
Jesper Louis Andersen
Browse files
Introduce tests for authentication verification and provide basis for signatures.
parent
ec0cc1af
Changes
5
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
57bb9368
...
...
@@ -6,3 +6,7 @@ ebin
*.eqc
*.so
eqc_test/.eqc-info
doc/edoc-info
doc/*.html
doc/*.png
doc/*.css
c_src/enacl_nif.c
View file @
57bb9368
...
...
@@ -304,11 +304,21 @@ ERL_NIF_TERM enif_crypto_stream_NONCEBYTES(ErlNifEnv *env, int argc, ERL_NIF_TER
return
enif_make_int64
(
env
,
crypto_stream_NONCEBYTES
);
}
static
ERL_NIF_TERM
enif_crypto_auth_BYTES
(
ErlNifEnv
*
env
,
int
argc
,
ERL_NIF_TERM
const
argv
[])
{
return
enif_make_int64
(
env
,
crypto_auth_BYTES
);
}
static
ERL_NIF_TERM
enif_crypto_auth_KEYBYTES
(
ErlNifEnv
*
env
,
int
argc
,
ERL_NIF_TERM
const
argv
[])
{
return
enif_make_int64
(
env
,
crypto_auth_KEYBYTES
);
}
static
ERL_NIF_TERM
enif_crypto_onetimeauth_BYTES
(
ErlNifEnv
*
env
,
int
argc
,
ERL_NIF_TERM
const
argv
[])
{
return
enif_make_int64
(
env
,
crypto_onetimeauth_BYTES
);
}
static
ERL_NIF_TERM
enif_crypto_onetimeauth_KEYBYTES
(
ErlNifEnv
*
env
,
int
argc
,
ERL_NIF_TERM
const
argv
[])
{
return
enif_make_int64
(
env
,
crypto_onetimeauth_KEYBYTES
);
...
...
@@ -571,10 +581,12 @@ static ErlNifFunc nif_funcs[] = {
{
"crypto_stream"
,
3
,
enif_crypto_stream
,
ERL_NIF_DIRTY_JOB_CPU_BOUND
},
{
"crypto_stream_xor"
,
3
,
enif_crypto_stream_xor
,
ERL_NIF_DIRTY_JOB_CPU_BOUND
},
{
"crypto_auth_BYTES"
,
0
,
enif_crypto_auth_BYTES
},
{
"crypto_auth_KEYBYTES"
,
0
,
enif_crypto_auth_KEYBYTES
},
{
"crypto_auth"
,
2
,
enif_crypto_auth
,
ERL_NIF_DIRTY_JOB_CPU_BOUND
},
{
"crypto_auth_verify"
,
3
,
enif_crypto_auth_verify
,
ERL_NIF_DIRTY_JOB_CPU_BOUND
},
{
"crypto_onetimeauth_BYTES"
,
0
,
enif_crypto_onetimeauth_BYTES
},
{
"crypto_onetimeauth_KEYBYTES"
,
0
,
enif_crypto_onetimeauth_KEYBYTES
},
{
"crypto_onetimeauth"
,
2
,
enif_crypto_onetimeauth
,
ERL_NIF_DIRTY_JOB_CPU_BOUND
},
{
"crypto_onetimeauth_verify"
,
3
,
enif_crypto_onetimeauth_verify
,
ERL_NIF_DIRTY_JOB_CPU_BOUND
},
...
...
eqc_test/enacl_eqc.erl
View file @
57bb9368
...
...
@@ -236,6 +236,45 @@ prop_auth_correct() ->
badargs
(
fun
()
->
enacl
:
auth
(
Msg
,
Key
)
end
)
end
).
authenticator_bad
()
->
oneof
([
a
,
int
(),
?
SUCHTHAT
(
X
,
binary
(),
byte_size
(
X
)
/=
enacl
:
auth_size
())]).
authenticator_good
(
Msg
,
Key
)
when
is_binary
(
Key
)
->
Sz
=
enacl
:
secretbox_key_size
(),
case
byte_size
(
Key
)
==
Sz
of
true
->
frequency
([{
1
,
?
LAZY
({
invalid
,
binary
(
enacl
:
auth_size
())})},
{
3
,
return
({
valid
,
enacl
:
auth
(
Msg
,
Key
)})}]);
false
->
binary
(
enacl
:
auth_size
())
end
;
authenticator_good
(_
Msg
,
_
Key
)
->
binary
(
enacl
:
auth_size
()).
authenticator
(
Msg
,
Key
)
->
fault
(
authenticator_bad
(),
authenticator_good
(
Msg
,
Key
)).
authenticator_valid
({
valid
,
_})
->
true
;
authenticator_valid
({
invalid
,
_})
->
true
;
authenticator_valid
(_)
->
false
.
prop_auth_verify_correct
()
->
?
FORALL
({
Msg
,
Key
},
{
binary
(),
fault_rate
(
1
,
40
,
secret_key
())},
?
FORALL
(
Authenticator
,
authenticator
(
Msg
,
Key
),
case
secret_key_valid
(
Key
)
andalso
authenticator_valid
(
Authenticator
)
of
true
->
case
Authenticator
of
{
valid
,
A
}
->
equals
(
true
,
enacl
:
auth_verify
(
A
,
Msg
,
Key
));
{
invalid
,
A
}
->
equals
(
false
,
enacl
:
auth_verify
(
A
,
Msg
,
Key
))
end
;
false
->
badargs
(
fun
()
->
enacl
:
auth_verify
(
Authenticator
,
Msg
,
Key
)
end
)
end
)).
%% CRYPTO ONETIME AUTH
prop_onetimeauth_correct
()
->
?
FORALL
({
Msg
,
Key
},
...
...
@@ -249,6 +288,45 @@ prop_onetimeauth_correct() ->
badargs
(
fun
()
->
enacl
:
onetime_auth
(
Msg
,
Key
)
end
)
end
).
ot_authenticator_bad
()
->
oneof
([
a
,
int
(),
?
SUCHTHAT
(
X
,
binary
(),
byte_size
(
X
)
/=
enacl
:
onetime_auth_size
())]).
ot_authenticator_good
(
Msg
,
Key
)
when
is_binary
(
Key
)
->
Sz
=
enacl
:
secretbox_key_size
(),
case
byte_size
(
Key
)
==
Sz
of
true
->
frequency
([{
1
,
?
LAZY
({
invalid
,
binary
(
enacl
:
onetime_auth_size
())})},
{
3
,
return
({
valid
,
enacl
:
onetime_auth
(
Msg
,
Key
)})}]);
false
->
binary
(
enacl
:
onetime_auth_size
())
end
;
ot_authenticator_good
(_
Msg
,
_
Key
)
->
binary
(
enacl
:
auth_size
()).
ot_authenticator
(
Msg
,
Key
)
->
fault
(
ot_authenticator_bad
(),
ot_authenticator_good
(
Msg
,
Key
)).
ot_authenticator_valid
({
valid
,
_})
->
true
;
ot_authenticator_valid
({
invalid
,
_})
->
true
;
ot_authenticator_valid
(_)
->
false
.
prop_onetime_auth_verify_correct
()
->
?
FORALL
({
Msg
,
Key
},
{
binary
(),
fault_rate
(
1
,
40
,
secret_key
())},
?
FORALL
(
Authenticator
,
ot_authenticator
(
Msg
,
Key
),
case
secret_key_valid
(
Key
)
andalso
ot_authenticator_valid
(
Authenticator
)
of
true
->
case
Authenticator
of
{
valid
,
A
}
->
equals
(
true
,
enacl
:
onetime_auth_verify
(
A
,
Msg
,
Key
));
{
invalid
,
A
}
->
equals
(
false
,
enacl
:
onetime_auth_verify
(
A
,
Msg
,
Key
))
end
;
false
->
badargs
(
fun
()
->
enacl
:
onetime_auth_verify
(
Authenticator
,
Msg
,
Key
)
end
)
end
)).
%% HASHING
%% ---------------------------
diff_pair
(
Sz
)
->
...
...
src/enacl.erl
View file @
57bb9368
...
...
@@ -23,7 +23,11 @@
box_open
/
4
,
box_nonce_size
/
0
,
box_public_key_bytes
/
0
,
box_secret_key_bytes
/
0
box_secret_key_bytes
/
0
,
sign_keypair
/
0
,
sign
/
2
,
sign_open
/
2
]).
%% Secret key crypto
...
...
@@ -39,10 +43,12 @@
stream_xor
/
3
,
auth_key_size
/
0
,
auth_size
/
0
,
auth
/
2
,
auth_verify
/
3
,
onetime_auth_key_size
/
0
,
onetime_auth_size
/
0
,
onetime_auth
/
2
,
onetime_auth_verify
/
3
]).
...
...
@@ -139,6 +145,38 @@ box_nonce_size() ->
box_public_key_bytes
()
->
enacl_nif
:
crypto_box_PUBLICKEYBYTES
().
%% Signatures
%% @doc sign_keypair/0 returns a signature keypair for signing
%% The returned value is a map in order to make it harder to misuse keys.
%% @end
-
spec
sign_keypair
()
->
KeyMap
when
KeyMap
::
maps
:
map
(
atom
(),
binary
()).
sign_keypair
()
->
{
PK
,
SK
}
=
enacl_nif
:
sign_keypair
(),
#
{
public
=>
PK
,
secret
=>
SK
}.
%% @doc sign/2 signs a message with a digital signature identified by a secret key.
%% Given a message `M' and a secret key `SK' the function will sign the message and return a signed message `SM'.
%% @end
-
spec
sign
(
M
,
SK
)
->
SM
when
M
::
binary
(),
SK
::
binary
(),
SM
::
binary
().
sign
(
M
,
SK
)
->
enacl_nif
:
sign
(
M
,
SK
).
%% @doc sign_open/2 opens a digital signature
%% Given a signed message `SM' and a public key `PK', verify that the message has the right signature. Returns either
%% `{ok, M}' or `{error, failed_verification}' depending on the correctness of the signature.
%% @end
-
spec
sign_open
(
SM
,
PK
)
->
{
ok
,
M
}
|
{
error
,
failed_verification
}
when
SM
::
binary
(),
PK
::
binary
(),
M
::
binary
().
sign_open
(
SM
,
PK
)
->
enacl_nif
:
sign_open
(
SM
,
PK
).
%% @private
-
spec
box_secret_key_bytes
()
->
pos_integer
().
box_secret_key_bytes
()
->
...
...
@@ -204,6 +242,11 @@ stream_xor(Msg, Nonce, Key) ->
-
spec
auth_key_size
()
->
pos_integer
().
auth_key_size
()
->
enacl_nif
:
crypto_auth_KEYBYTES
().
%% @doc auth_size/0 returns the byte-size of the authenticator
%% @end
-
spec
auth_size
()
->
pos_integer
().
auth_size
()
->
enacl_nif
:
crypto_auth_BYTES
().
%% @doc auth/2 produces an authenticator (MAC) for a message
%% Given a `Msg' and a `Key' produce a MAC/Authenticator for that message. The key can be reused for several such Msg/Authenticator pairs.
%% An eavesdropper will not learn anything extra about the message structure.
...
...
@@ -239,7 +282,7 @@ onetime_auth(Msg, Key) -> enacl_nif:crypto_onetimeauth(Msg, Key).
%% @doc onetime_auth_verify/3 verifies an ONE-TIME authenticator for a message
%% Given an `Authenticator', a `Msg' and a `Key'; verify that the MAC for the pair `{Msg, Key}' is really `Authenticator'. Returns
%% the value `true' if the verfication passes. Upon failure, the function returns `false'. Note the caveat from {@link onetime_auth/2}
%% the value `true' if the ver
i
fication passes. Upon failure, the function returns `false'. Note the caveat from {@link onetime_auth/2}
%% applies: you are not allowed to ever use the same key again for another message.
%% @end
-
spec
onetime_auth_verify
(
Authenticator
,
Msg
,
Key
)
->
boolean
()
...
...
@@ -249,6 +292,11 @@ onetime_auth(Msg, Key) -> enacl_nif:crypto_onetimeauth(Msg, Key).
Key
::
binary
().
onetime_auth_verify
(
A
,
M
,
K
)
->
enacl_nif
:
crypto_onetimeauth_verify
(
A
,
M
,
K
).
%% @doc onetime_auth_size/0 returns the number of bytes of the one-time authenticator
%% @end
-
spec
onetime_auth_size
()
->
pos_integer
().
onetime_auth_size
()
->
enacl_nif
:
crypto_onetimeauth_BYTES
().
%% @doc onetime_auth_key_size/0 returns the byte-size of the onetime authentication key
%% @end
-
spec
onetime_auth_key_size
()
->
pos_integer
().
...
...
src/enacl_nif.erl
View file @
57bb9368
...
...
@@ -35,10 +35,12 @@
crypto_stream
/
3
,
crypto_stream_xor
/
3
,
crypto_auth_BYTES
/
0
,
crypto_auth_KEYBYTES
/
0
,
crypto_auth
/
2
,
crypto_auth_verify
/
3
,
crypto_onetimeauth_BYTES
/
0
,
crypto_onetimeauth_KEYBYTES
/
0
,
crypto_onetimeauth
/
2
,
crypto_onetimeauth_verify
/
3
...
...
@@ -93,10 +95,12 @@ crypto_stream_NONCEBYTES() -> not_loaded().
crypto_stream
(_
Bytes
,
_
Nonce
,
_
Key
)
->
not_loaded
().
crypto_stream_xor
(_
M
,
_
Nonce
,
_
Key
)
->
not_loaded
().
crypto_auth_BYTES
()
->
not_loaded
().
crypto_auth_KEYBYTES
()
->
not_loaded
().
crypto_auth
(_
Msg
,
_
Key
)
->
not_loaded
().
crypto_auth_verify
(_
Authenticator
,
_
Msg
,
_
Key
)
->
not_loaded
().
crypto_onetimeauth_BYTES
()
->
not_loaded
().
crypto_onetimeauth_KEYBYTES
()
->
not_loaded
().
crypto_onetimeauth
(_
Msg
,
_
Key
)
->
not_loaded
().
crypto_onetimeauth_verify
(_
Authenticator
,
_
Msg
,
_
Key
)
->
not_loaded
().
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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