1%% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*-
2%% vim: ts=4 sw=4 ft=erlang noet
3-module(jose_jwk_kty_okp_ed25519ph_props).
4
5-include_lib("public_key/include/public_key.hrl").
6
7-include_lib("proper/include/proper.hrl").
8
9% -compile(export_all).
10
11base64url_binary() ->
12	?LET(Binary,
13		binary(),
14		jose_jwa_base64url:encode(Binary)).
15
16binary_map() ->
17	?LET(List,
18		list({base64url_binary(), base64url_binary()}),
19		maps:from_list(List)).
20
21ed25519ph_secret() ->
22	binary(32).
23
24ed25519ph_keypair(Secret) ->
25	{PK, SK} = jose_curve25519:eddsa_keypair(Secret),
26	{SK, PK}.
27
28jwk_map() ->
29	?LET({AliceSecret, BobSecret},
30		{ed25519ph_secret(), ed25519ph_secret()},
31		begin
32			AliceKeys = {AlicePrivateKey, _} = ed25519ph_keypair(AliceSecret),
33			BobKeys = ed25519ph_keypair(BobSecret),
34			AlicePrivateJWK = jose_jwk:from_okp({'Ed25519ph', AlicePrivateKey}),
35			{_, AlicePrivateJWKMap} = jose_jwk:to_map(AlicePrivateJWK),
36			Keys = {AliceKeys, BobKeys},
37			{Keys, AlicePrivateJWKMap}
38		end).
39
40jwk_gen() ->
41	?LET({Keys, AlicePrivateJWKMap},
42		jwk_map(),
43		{Keys, jose_jwk:from_map(AlicePrivateJWKMap)}).
44
45prop_from_map_and_to_map() ->
46	?FORALL({{{AlicePrivateKey, AlicePublicKey}, _}, AlicePrivateJWKMap},
47		?LET({{Keys, JWKMap}, Extras},
48			{jwk_map(), binary_map()},
49			{Keys, maps:merge(Extras, JWKMap)}),
50		begin
51			AlicePrivateJWK = jose_jwk:from_map(AlicePrivateJWKMap),
52			AlicePublicJWK = jose_jwk:to_public(AlicePrivateJWK),
53			AlicePublicJWKMap = element(2, jose_jwk:to_map(AlicePublicJWK)),
54			AlicePublicThumbprint = jose_jwk:thumbprint(AlicePublicJWK),
55			AlicePrivateJWKMap =:= element(2, jose_jwk:to_map(AlicePrivateJWK))
56			andalso AlicePrivateKey =:= element(2, jose_jwk:to_key(AlicePrivateJWK))
57			andalso AlicePublicKey =:= element(2, jose_jwk:to_public_key(AlicePrivateJWK))
58			andalso AlicePublicJWKMap =:= element(2, jose_jwk:to_public_map(AlicePrivateJWK))
59			andalso AlicePublicThumbprint =:= jose_jwk:thumbprint(AlicePrivateJWK)
60		end).
61
62prop_sign_and_verify() ->
63	?FORALL({_Keys, JWK, Message},
64		?LET({Keys, JWK},
65			jwk_gen(),
66			{Keys, JWK, binary()}),
67		begin
68			Signed = jose_jwk:sign(Message, JWK),
69			CompactSigned = jose_jws:compact(Signed),
70			Verified = {_, _, JWS} = jose_jwk:verify(Signed, JWK),
71			{true, Message, JWS} =:= Verified
72			andalso {true, Message, JWS} =:= jose_jwk:verify(CompactSigned, JWK)
73		end).
74