# Crypto Module
% this function will return each supported algorithms
% in list [{hashs, _}, {ciphers, _}, {public_keys, _}]
crypto:support().
% this function will return all available exported
% APIs function
crypto:info().
% will return used library and systems
crypto:info_lib().
% will return version library
crypto:version().
% generate random bytes
crypto:rand_bytes(32).
% xor two iolist and return result
crypto:exor(<<"test">>, <<"test">>).
% return <<0,0,0,0>>
crypto:exor(<<"random">>, <<"toptop">>).
%return crypto:exor(<<"random">>, <<"toptop">>).
% generate big value through nif
% last arguments is the base
% python equivalence: 15**15 % 16
crypto:mod_pow(15, 15, 16).
% return <<15>>
% hash functions are really simple
% note: using this way all funtions are not fully exported
DATA = <<"test">>.
crypto:md5(DATA).
crypto:sha(DATA).
crypto:sha224(DATA).
crypto:sha256(DATA).
crypto:sha512(DATA).
% another method with hash function.
MSG = <<"test">>.
crypto:hash(md5, MSG).
crypto:hash(ripemd160, MSG).
crypto:hash(sha, MSG).
crypto:hash(sha224, MSG).
crypto:hash(sha256, MSG).
crypto:hash(sha384, MSG).
crypto:hash(sha512, MSG).
KEY=<<"thisisyourkey">>.
DATA=<<"thisisyourdata">>.
crypto:hmac(md5, KEY, DATA).
crypto:hmac(sha, KEY, DATA).
crypto:hmac(sha224, KEY, DATA).
crypto:hmac(sha256, KEY, DATA).
crypto:hmac(sha384, KEY, DATA).
crypto:hmac(sha512, KEY, DATA).
% first, we start crypto application (which launch nif crypto)
crypto:start()
% we will try some algorithm for test
% We can create IVs for each cipher with algoname_mode_ivec function
% IVs are fixed length.
DES_CBC_IV = crypto:des_cbc_ivec(crypto:rand_bytes(16)).
% des key is fixed to 56bits + 8bits, so 64bits/8bytes
DES_CBC_KEY = crypto:rand_bytes(8).
% cbc need fixed length, messages need to be equal to 8bytes or
% padded.
DES_CBC_MSG = crypto:rand_bytes(8).
% this return the encrypted message.
DES_CIPHER = crypto:des_cbc_encrypt(DES_CBC_KEY, DES_CBC_IV, DES_CBC_MSG).
% your plaintext need to be padded, or exactly
% measuring 128bits.
PlainText = <<"">>
% one padding method, return a list of bitstring.
MsgPaddingWithList =
fun P(<<Head:128/bitstring, Tail/bitstring>>, Acc) -> P(Tail, Acc ++ [Head]);
P(<<Rest/bitstring>>, Acc) ->
RestSize = 128 - bit_size(Rest),
Padding = << <<X:1>> || X <- lists:map(fun(_) -> 0 end, lists:seq(1,RestSize)) >>,
Acc ++ [<<Rest/bitstring, Padding/bitstring>>]
end.
% another padding method, work directly with bitstring
MsgPaddingWithIfGuards =
fun P(Data) when is_bitstring(Data) ->
PaddingSize = 128 - (bit_size(Data) rem 128),
if PaddingSize =:= 0 ->
Data;
true ->
Padding = << <<X:1>> || X <- lists:map(fun(_) -> 0 end, lists:seq(1,PaddingSize)) >>,
<<Data/bitstring, Padding/bitstring>>
end
end.
% same function with fun pattern matching and list support
MessagePadding =
fun P(Data) when is_list(Data) -> P(list_to_binary(Data));
P(Data) when is_bitstring(Data),
bit_size(Data) rem 128 =:= 0 -> Data;
P(Data) when is_bitstring(Data),
bit_size(Data) rem 128 =/= 0 ->
PaddingSize = 128 - (bit_size(Data) rem 128),
PaddingGen = lists:map(fun(_) -> 0 end, lists:seq(1, PaddingSize)),
Padding = << <<X:1>> || X <- PaddingGen >>,
<<Data/bitstring, Padding/bitstring >>
end.
% remove padding from unencrypted message
MessageRemovePadding =
fun P(Data) when is_list(Data) -> P(list_to_binary(Data));
P(Data) when is_bitstring(Data) ->
<< <<X>> || <<X>> <= Data, X =/= 0 >>
end.
% Here your password
Password = <<"ThisIsMyPassword">>.
% aes use a key space of 128bits or 256bits. In this
% example I will use aes 128. So, if the password is
% too long, we need to shrink it. The best way for doing
% that is to use a hash function.
PasswordHash = crypto:hash(sha512, Password).
<<Key:128/bitstring, _/bitstring>> = PasswordHash.
% IV (initialization vector) is publicly known and
% need to be random.
IV = crypto:rand_bytes(16).
% we can now encrypt with aes128 cbc:
C = crypto:aes_cbc_128_encrypt(Key, IV, MessagePadding(PlainText)).
% Ciphertext could be decrypted with decrypt function:
P = MessageRemovePadding(crypto:aes_cbc_128_decrypt(Key, IV, C)).
KEY=crypto:rand_bytes(16). % key
IV=crypto:rand_bytes(16). % init vector
AAD=crypto:rand_bytes(16). % authentification data
MSG=crypto:rand_bytes(16). % plain text
crypto:block_encrypt(aes_gcm, KEY, IV, {AAD, MSG}).
# ETF
% encoding
erlang:term_to_binary().
% decoding
erlang:binary_to_term().
/* standard function: printf
* file descriptor management: fdopen, fclose
*/
#include <stdio.h>
/* memory management; malloc, free */
#include <stdlib.h>
/* memory sanitize: memset */
#incluse <string.h>
/* main Erlang interface header for
* encoding, decoding and manage memory with
* ei_* and ei_x_* functions
*/
#include "ei.h"
# GNU Makefile
# set erlang path, in /usr/lib/erlang or /usr/local/lib/erlang
ERLANG_PATH ?= /usr/local/lib/erlang/lib
ERLANG_LIBRARY_PATH := $(ERLANG_PATH)/usr
ERLANG_INCLUDE_PATH := $(ERLANG_PATH)/include
ERLANG_LIBRARIES := ei
# include erlang library and headers
CC_ERLANG_PATH := -L${ERLANG_LIBRARY_PATH} -I${ERLANG_INCLUDE_PATH}
# expand all used erlang libraries (ei in our case)
CC_ERLANG_LIBS := $(foreach lib, $(ERLANG_LIBRARIES), -l$(lib))
CC_OPTS := -Wall $(CC_ERLANG_PATH) $(CC_ERLANG_LIBS)
CC := cc
help:
@echo Usage: make build TARGET=mysource.c
build:
# if TARGET variable is set, build it...
ifdef TARGET
$(CC) $(CC_OPTS) $(TARGET) $(CC_ERLANG_LIBS)
# else return an error
else
@echo "please set TARGET parameter
endif
int
main(void) {
int index = 0; // buffer index
char buffer[1024]; // buffer allocated on the stack
memset(buffer, 0, 1024); // sanitize buffer
}
int
main(void) {
int index = 0; // buffer index
char buffer[1024]; // buffer allocated on the stack
memset(buffer, 0, 1024); // sanitize buffer
}
# httpd
%%% Start
Config = [mod_alias, mod_auth, mod_esi, mod_damn],
inets:start(),
inets:start(httpd, Config).
%%% Info
Pid = proplists:get_value(httpd, httpd:services()),
httpd:service_info(Pid).
%%% Stop
Pid = proplists:get_value(httpd, httpd:services()),
inets:stop(httpd, Pid).
# xmerl
% Parsing stream in erlang is straightforward, with sax method
ContinuationFun = fun(X) ->
io:format("~p~n", [X])
end.
EventFun = fun(Event, Location, State) ->
io:format("event: ~p~n", [Event]),
io:format("location: ~p~n", [Location]),
io:format("state: ~p~n", [State])
end.
xmerl_sax_parser:stream(YourStreamHere, [{continuation_fun, ContinuationFun, {event_fun, EventFun}])
% parsing html page
inets:start().
inets:start(httpc, [{profile, httpc}]).
{ok, {_,_,Page} = httpc:request("http://yoururl.com").
ContinuationFun = fun(X) ->
io:format("~p~n", [X])
end.
EventFun = fun(Event, Location, State) ->
io:format("event: ~p~n", [Event]),
io:format("location: ~p~n", [Location]),
io:format("state: ~p~n", [State])
end.
xmerl_sax_parser:stream(page, [{continuation_fun, ContinuationFun}, {event_fun, EventFun}].
# merl
merl:quote("inc(X, Y) when Y > 0 -> X + Y. t() -> ok.").
returned data:
[{function,1,inc,2,
[{clause,1,
[{var,1,'X'},{var,1,'Y'}],
[[{op,1,'>',{var,1,'Y'},{integer,1,0}}]],
[{op,1,'+',{var,1,'X'},{var,1,'Y'}}]}]},
{function,1,t,0,[{clause,1,[],[],[{atom,1,ok}]}]}]
MyCode = "-module(test). -export([t/0]). t () -> ok.".
MyAST = merl:quote(MyCode.)
merl:compile_and_load(MyAST).
test:t().
# network configuration
TODO
- http://erlang.org/pipermail/erlang-questions/2011-April/057850.html
- http://erlang.org/faq/how_do_i.html#idp32278352
- http://erlang.org/doc/man/kernel_app.html
- http://stackoverflow.com/questions/2369341
- http://erlang.org/doc/apps/erts/erl_dist_protocol.html
# NIFs
TODO
- you need to create two distinct files, C and Erlang file. You can also create Makefile if you want.
- Makefile will contain all compile rules
← アタエタ