aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/test/crypto_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto/test/crypto_SUITE.erl')
-rw-r--r--lib/crypto/test/crypto_SUITE.erl258
1 files changed, 203 insertions, 55 deletions
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index c007ecac86..58aaa78d28 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -48,7 +48,7 @@ all() ->
{group, des_cfb},
{group, des3_cbc},
{group, des3_cbf},
- %%{group, des_ede3},
+ {group, des_ede3},
{group, blowfish_cbc},
{group, blowfish_ecb},
{group, blowfish_cfb64},
@@ -60,7 +60,8 @@ all() ->
{group, rc4},
{group, aes_ctr},
mod_pow,
- exor
+ exor,
+ rand_uniform
].
groups() ->
@@ -83,6 +84,7 @@ groups() ->
{des_cbc, [], [block]},
{des_cfb, [], [block]},
{des3_cbc,[], [block]},
+ {des_ede3,[], [block]},
{des3_cbf,[], [block]},
{rc2_cbc,[], [block]},
{aes_cbc128,[], [block]},
@@ -210,21 +212,19 @@ mod_pow(Config) when is_list(Config) ->
exor() ->
[{doc, "Test the exor function"}].
exor(Config) when is_list(Config) ->
- B = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>,
- Z1 = zero_bin(B),
- Z1 = crypto:exor(B, B),
- B1 = crypto:rand_bytes(100),
- B2 = crypto:rand_bytes(100),
- Z2 = zero_bin(B1),
- Z2 = crypto:exor(B1, B1),
- Z2 = crypto:exor(B2, B2),
- R = xor_bytes(B1, B2),
- R = crypto:exor(B1, B2).
+ do_exor(<<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>),
+ do_exor(term_to_binary(lists:seq(1, 1000000))).
+%%--------------------------------------------------------------------
+rand_uniform() ->
+ [{doc, "rand_uniform and random_bytes testing"}].
+rand_uniform(Config) when is_list(Config) ->
+ rand_uniform_aux_test(10),
+ 10 = byte_size(crypto:rand_bytes(10)),
+ 10 = byte_size(crypto:strong_rand_bytes(10)).
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
-
hash(_, [], []) ->
ok;
hash(Type, [Msg | RestMsg], [Digest| RestDigest]) ->
@@ -398,16 +398,19 @@ negative_verify(Type, Hash, Msg, Signature, Public) ->
end.
do_public_encrypt({Type, Public, Private, Msg, Padding}) ->
- PublicEcn = crypto:public_encrypt(Type, Msg, Public, Padding),
+ PublicEcn = (catch crypto:public_encrypt(Type, Msg, Public, Padding)),
case crypto:private_decrypt(Type, PublicEcn, Private, Padding) of
Msg ->
ok;
Other ->
ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, Other}})
end.
+
+do_private_encrypt({_Type, _Public, _Private, _Msg, rsa_pkcs1_oaep_padding}) ->
+ ok; %% Not supported by openssl
do_private_encrypt({Type, Public, Private, Msg, Padding}) ->
- PrivEcn = crypto:private_encrypt(Type, Msg, Private, Padding),
- case crypto:public_decrypt(Type, PrivEcn, Public, Padding) of
+ PrivEcn = (catch crypto:private_encrypt(Type, Msg, Private, Padding)),
+ case crypto:public_decrypt(rsa, PrivEcn, Public, Padding) of
Msg ->
ok;
Other ->
@@ -451,8 +454,6 @@ mkint(C) when $A =< C, C =< $F ->
mkint(C) when $a =< C, C =< $f ->
C - $a + 10.
-is_supported(cipher) ->
- true;
is_supported(Group) ->
lists:member(Group, lists:append([Algo || {_, Algo} <- crypto:supports()])).
@@ -472,6 +473,8 @@ do_block_iolistify({des3_cbc = Type, Key, IV, PlainText}) ->
{Type, Key, IV, des_iolistify(PlainText)};
do_block_iolistify({des3_cbf = Type, Key, IV, PlainText}) ->
{Type, Key, IV, des_iolistify(PlainText)};
+do_block_iolistify({des_ede3 = Type, Key, IV, PlainText}) ->
+ {Type, Key, IV, des_iolistify(PlainText)};
do_block_iolistify({Type, Key, PlainText}) ->
{Type, iolistify(Key), iolistify(PlainText)};
do_block_iolistify({Type, Key, IV, PlainText}) ->
@@ -480,7 +483,7 @@ do_block_iolistify({Type, Key, IV, PlainText}) ->
iolistify(<<"Test With Truncation">>)->
%% Do not iolistify as it spoils this special case
<<"Test With Truncation">>;
-iolistify(Msg)->
+iolistify(Msg) when is_binary(Msg) ->
Length = erlang:byte_size(Msg),
Split = Length div 2,
List0 = binary_to_list(Msg),
@@ -489,7 +492,9 @@ iolistify(Msg)->
[[Element], List1, List2];
{List1, List2}->
[List1, List2]
- end.
+ end;
+iolistify(Msg) ->
+ iolistify(list_to_binary(Msg)).
des_iolistify(Msg) ->
des_iolist(erlang:byte_size(Msg) div 8, Msg, []).
@@ -529,6 +534,17 @@ ipow(A, B, M, Prod) ->
ipow(A1, B1, M, (A*Prod) rem M)
end.
+do_exor(B) ->
+ Z1 = zero_bin(B),
+ Z1 = crypto:exor(B, B),
+ B1 = crypto:rand_bytes(100),
+ B2 = crypto:rand_bytes(100),
+ Z2 = zero_bin(B1),
+ Z2 = crypto:exor(B1, B1),
+ Z2 = crypto:exor(B2, B2),
+ R = xor_bytes(B1, B2),
+ R = crypto:exor(B1, B2).
+
zero_bin(N) when is_integer(N) ->
N8 = N * 8,
<<0:N8/integer>>;
@@ -545,6 +561,25 @@ xor_bytes([], [], Acc) ->
lists:reverse(Acc);
xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) ->
xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]).
+rand_uniform_aux_test(0) ->
+ ok;
+rand_uniform_aux_test(N) ->
+ L = N*1000,
+ H = N*100000+1,
+ crypto_rand_uniform(L, H),
+ crypto_rand_uniform(-L, L),
+ crypto_rand_uniform(-H, -L),
+ crypto_rand_uniform(-H, L),
+ rand_uniform_aux_test(N-1).
+
+crypto_rand_uniform(L,H) ->
+ R1 = crypto:rand_uniform(L, H),
+ case (R1 >= L) and (R1 < H) of
+ true ->
+ ok;
+ false ->
+ ct:fail({"Not in interval", R1, L, H})
+ end.
%%--------------------------------------------------------------------
%% Test data ------------------------------------------------
@@ -556,20 +591,20 @@ group_config(md4 = Type, Config) ->
group_config(md5 = Type, Config) ->
Msgs = rfc_1321_msgs(),
Digests = rfc_1321_md5_digests(),
- Keys = rfc_2202_md5_keys(),
- Data = rfc_2202_msgs(),
- Hmac = rfc_2202_hmac_md5(),
+ Keys = rfc_2202_md5_keys() ++ [long_hmac_key(md5)],
+ Data = rfc_2202_msgs() ++ [long_msg()],
+ Hmac = rfc_2202_hmac_md5() ++ [long_hmac(md5)],
[{hash, {Type, Msgs, Digests}}, {hmac, {Type, Keys, Data, Hmac}} | Config];
group_config(ripemd160 = Type, Config) ->
Msgs = ripemd160_msgs(),
Digests = ripemd160_digests(),
[{hash, {Type, Msgs, Digests}} | Config];
group_config(sha = Type, Config) ->
- Msgs = [rfc_4634_test1(), rfc_4634_test2_1()],
- Digests = rfc_4634_sha_digests(),
- Keys = rfc_2202_sha_keys(),
- Data = rfc_2202_msgs(),
- Hmac = rfc_2202_hmac_sha(),
+ Msgs = [rfc_4634_test1(), rfc_4634_test2_1(),long_msg()],
+ Digests = rfc_4634_sha_digests() ++ [long_sha_digest()],
+ Keys = rfc_2202_sha_keys() ++ [long_hmac_key(sha)],
+ Data = rfc_2202_msgs() ++ [long_msg()],
+ Hmac = rfc_2202_hmac_sha() ++ [long_hmac(sha)],
[{hash, {Type, Msgs, Digests}}, {hmac, {Type, Keys, Data, Hmac}} | Config];
group_config(sha224 = Type, Config) ->
Msgs = [rfc_4634_test1(), rfc_4634_test2_1()],
@@ -579,41 +614,37 @@ group_config(sha224 = Type, Config) ->
Hmac = rfc4231_hmac_sha224(),
[{hash, {Type, Msgs, Digests}}, {hmac, {Type, Keys, Data, Hmac}} | Config];
group_config(sha256 = Type, Config) ->
- Msgs = [rfc_4634_test1(), rfc_4634_test2_1()],
- Digests = rfc_4634_sha256_digests(),
- Keys = rfc_4231_keys(),
- Data = rfc_4231_msgs(),
- Hmac = rfc4231_hmac_sha256(),
+ Msgs = [rfc_4634_test1(), rfc_4634_test2_1(), long_msg()],
+ Digests = rfc_4634_sha256_digests() ++ [long_sha256_digest()],
+ Keys = rfc_4231_keys() ++ [long_hmac_key(sha256)],
+ Data = rfc_4231_msgs() ++ [long_msg()],
+ Hmac = rfc4231_hmac_sha256() ++ [long_hmac(sha256)],
[{hash, {Type, Msgs, Digests}}, {hmac, {Type, Keys, Data, Hmac}} | Config];
group_config(sha384 = Type, Config) ->
- Msgs = [rfc_4634_test1(), rfc_4634_test2()],
- Digests = rfc_4634_sha384_digests(),
- Keys = rfc_4231_keys(),
- Data = rfc_4231_msgs(),
- Hmac = rfc4231_hmac_sha384(),
+ Msgs = [rfc_4634_test1(), rfc_4634_test2(), long_msg()],
+ Digests = rfc_4634_sha384_digests() ++ [long_sha384_digest()],
+ Keys = rfc_4231_keys() ++ [long_hmac_key(sha384)],
+ Data = rfc_4231_msgs() ++ [long_msg()],
+ Hmac = rfc4231_hmac_sha384() ++ [long_hmac(sha384)],
[{hash, {Type, Msgs, Digests}}, {hmac, {Type, Keys, Data, Hmac}} | Config];
group_config(sha512 = Type, Config) ->
- Msgs = [rfc_4634_test1(), rfc_4634_test2()],
- Digests = rfc_4634_sha512_digests(),
- Keys = rfc_4231_keys(),
- Data = rfc_4231_msgs(),
- Hmac = rfc4231_hmac_sha512(),
+ Msgs = [rfc_4634_test1(), rfc_4634_test2(), long_msg()],
+ Digests = rfc_4634_sha512_digests() ++ [long_sha512_digest()],
+ Keys = rfc_4231_keys() ++ [long_hmac_key(sha512)],
+ Data = rfc_4231_msgs() ++ [long_msg()],
+ Hmac = rfc4231_hmac_sha512() ++ [long_hmac(sha512)],
[{hash, {Type, Msgs, Digests}}, {hmac, {Type, Keys, Data, Hmac}} | Config];
group_config(rsa = Type, Config) ->
Msg = rsa_plain(),
Public = rsa_public(),
Private = rsa_private(),
- SignVerify = [{Type, md5, Public, Private, Msg},
- {Type, sha, Public, Private, Msg},
- {Type, sha224, Public, Private,Msg},
- {Type, sha256, Public, Private,Msg}
- %% {Type, sha384, Public, Private,Msg},
- %% {Type, sha512, Public, Private, Msg}
- ],
+ PublicS = rsa_public_stronger(),
+ PrivateS = rsa_private_stronger(),
+ SignVerify = sign_verify_tests(Type, Msg, Public, Private, PublicS, PrivateS),
MsgPubEnc = <<"7896345786348 Asldi">>,
- PubPrivEnc = [{rsa, Public, Private, MsgPubEnc, rsa_pkcs1_padding}
- %%{rsa, Public, Private, MsgPubEnc, rsa_pkcs1_oaep_padding}
- %%{rsa, Public, Private, MsgPubEnc, rsa_no_padding}
+ PubPrivEnc = [{rsa, Public, Private, MsgPubEnc, rsa_pkcs1_padding},
+ rsa_oaep(),
+ no_padding()
],
[{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc} | Config];
group_config(dss = Type, Config) ->
@@ -649,6 +680,9 @@ group_config(des3_cbc, Config) ->
group_config(des3_cbf, Config) ->
Block = des3_cbf(),
[{block, Block} | Config];
+group_config(des_ede3, Config) ->
+ Block = des_ede3(),
+ [{block, Block} | Config];
group_config(rc2_cbc, Config) ->
Block = rc2_cbc(),
[{block, Block} | Config];
@@ -682,6 +716,20 @@ group_config(aes_ctr, Config) ->
group_config(_, Config) ->
Config.
+sign_verify_tests(Type, Msg, Public, Private, PublicS, PrivateS) ->
+ sign_verify_tests(Type, [md5, sha, sha224, sha256], Msg, Public, Private) ++
+ sign_verify_tests(Type, [sha384, sha512], Msg, PublicS, PrivateS).
+
+sign_verify_tests(Type, Hashs, Msg, Public, Private) ->
+ lists:foldl(fun(Hash, Acc) ->
+ case is_supported(Hash) of
+ true ->
+ [{Type, Hash, Public, Private, Msg}|Acc];
+ false ->
+ Acc
+ end
+ end, [], Hashs).
+
rfc_1321_msgs() ->
[<<"">>,
<<"a">>,
@@ -746,6 +794,23 @@ rfc_4634_sha512_digests() ->
"454D4423643CE80E2A9AC94FA54CA49F"),
hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909")].
+long_msg() ->
+ lists:duplicate(1000000, $a).
+
+long_sha_digest() ->
+ hexstr2bin("34aa973c" "d4c4daa4" "f61eeb2b" "dbad2731" "6534016f").
+
+long_sha256_digest() ->
+ hexstr2bin("cdc76e5c" "9914fb92" "81a1c7e2" "84d73e67" "f1809a48" "a497200e" "046d39cc" "c7112cd0").
+
+long_sha384_digest() ->
+ hexstr2bin("9d0e1809716474cb" "086e834e310a4a1c" "ed149e9c00f24852" "7972cec5704c2a5b"
+ "07b8b3dc38ecc4eb" "ae97ddd87f3d8985").
+
+long_sha512_digest() ->
+ hexstr2bin("e718483d0ce76964" "4e2e42c7bc15b463" "8e1f98b13b204428" "5632a803afa973eb"
+ "de0ff244877ea60a" "4cb0432ce577c31b" "eb009c5c2c49aa2e" "4eadb217ad8cc09b").
+
ripemd160_msgs() ->
[<<"">>,
<<"a">>,
@@ -809,6 +874,35 @@ hmac_key(_) ->
hmac_inc(_) ->
[<<"Sampl">>, <<"e #1">>].
+%% https://www.cosic.esat.kuleuven.be/nessie/testvectors/
+long_hmac_key(Type) when Type == sha384;
+ Type == sha512 ->
+ hexstr2bin("00112233445566778899AABBCCDDEEFF"
+ "0123456789ABCDEF0011223344556677"
+ "8899AABBCCDDEEFF0123456789ABCDEF"
+ "00112233445566778899AABBCCDDEEFF");
+long_hmac_key(_) ->
+ hexstr2bin("0123456789ABCDEF0123456789ABCDEF"
+ "0123456789ABCDEF0123456789ABCDEF"
+ "0123456789ABCDEF0123456789ABCDEF"
+ "0123456789ABCDEF0123456789ABCDEF").
+long_hmac(md5) ->
+ hexstr2bin("82FDDA30202CB6ACC6F24D4F8A50EB7A");
+long_hmac(sha) ->
+ hexstr2bin("61D1D0B6459860755FDA892938C23DD401E54A7E");
+long_hmac(sha256) ->
+ hexstr2bin("50008B8DC7ED3926936347FDC1A01E9D"
+ "5220C6CC4B038B482C0F28A4CD88CA37");
+long_hmac(sha384) ->
+ hexstr2bin("C1EB08DAFA015833D3FC6B29A387558B"
+ "3F6FA1524AA1A8EB64798D5A76A39D6E"
+ "A1465525342E060EE996277B4FFCDDC9");
+long_hmac(sha512) ->
+ hexstr2bin("D116BF471AAE1264854F1906025E846A"
+ "61618A965FCA30B695220EA2D6E547E3"
+ "F3B5A4B54E6778928C26D5D3D810498E"
+ "8DF86CB3CC1E9F66A00419B13B6B0C9A").
+
rfc_2202_hmac_md5() ->
[
hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d"),
@@ -950,6 +1044,15 @@ des3_cbc() ->
<<"Now is the time for all ">>
}].
+des_ede3() ->
+ [{des_ede3,
+ [hexstr2bin("8000000000000000"),
+ hexstr2bin("4000000000000000"),
+ hexstr2bin("2000000000000000")],
+ hexstr2bin("7AD16FFB79C45926"),
+ hexstr2bin("0000000000000000")
+ }].
+
des3_cbf() ->
[{des3_cbf,
[hexstr2bin("0123456789abcdef"),
@@ -1141,7 +1244,8 @@ blowfish_ofb64() ->
rc4() ->
[{rc4, <<"apaapa">>, <<"Yo baby yo">>},
- {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))}
+ {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))},
+ {rc4, <<"apaapa">>, lists:duplicate(1000000, $a)}
].
aes_ctr() ->
@@ -1185,7 +1289,11 @@ aes_ctr() ->
hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
{aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
+ hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
+
+ {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
+ hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
+ lists:duplicate(1000000, $a)}
].
rsa_plain() ->
@@ -1196,6 +1304,12 @@ rsa_public() ->
rsa_private() ->
rsa_public() ++ [7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945].
+rsa_public_stronger() ->
+ [65537, 24629450921918866883077380602720734920775458960049554761386137065662137652635369332143446151320538248280934442179850504891395344346514465469955766163141133564033962851182759993807898821114734943339732032639891483186089941567854227407119560631150779000222837755424893038740314247760600374970909894211201220612920040986106639419467243909950276018045907029941478599124238353052062083560294570722081552510960894164859765695309596889747541376908786225647625736062865138957717982693312699025417086612046330464651009693307624955796202070510577399561730651967517158452930742355327167632521808183383868100102455048819375344881].
+
+rsa_private_stronger() ->
+ rsa_public_stronger() ++ [13565232776562604620467234237694854016819673873109064019820773052201665024482754648718278717031083946624786145611240731564761987114634269887293030432042088547345315212418830656522115993209293567218379960177754901461542373481136856927955012596579314262051109321754382091434920473734937991286600905464814063189230779981494358415076362038786197620360127262110530926733754185204773610295221669711309000953136320804528874719105049753061737780710448207922456570922652651354760939379096788728229638142403068102990416717272880560951246813789730402978652924934794503277969128609831043469924881848849409122972426787999886557185].
+
dss_plain() ->
rsa_plain().
dss_public() ->
@@ -1355,3 +1469,37 @@ ecdh() ->
dh() ->
{dh, 0087761979513264537414556992123116644042638206717762626089877284926656954974893442000747478454809111207351620687968672207938731607963470779396984752680274820156266685080223616226905101126463253150237669547023934604953898814222890239130021414026118792251620881355456432549881723310342870016961804255746630219, 2}.
+
+rsa_oaep() ->
+ %% ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt
+ Public = [hexstr2bin("010001"),
+ hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
+ Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
+ hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
+ hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
+ hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
+ hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
+ hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
+ %%Msg = hexstr2bin("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"),
+ Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
+ {rsa, Public, Private, Msg, rsa_pkcs1_oaep_padding}.
+
+no_padding() ->
+ Public = [_, Mod] = rsa_public(),
+ Private = rsa_private(),
+ MsgLen = erlang:byte_size(int_to_bin(Mod)),
+ Msg = list_to_binary(lists:duplicate(MsgLen, $X)),
+ {rsa, Public, Private, Msg, rsa_no_padding}.
+
+int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []);
+int_to_bin(X) -> int_to_bin_pos(X, []).
+
+int_to_bin_pos(0,Ds=[_|_]) ->
+ list_to_binary(Ds);
+int_to_bin_pos(X,Ds) ->
+ int_to_bin_pos(X bsr 8, [(X band 255)|Ds]).
+
+int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
+ list_to_binary(Ds);
+int_to_bin_neg(X,Ds) ->
+ int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).