Skip to content

Commit

Permalink
Documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ndpar committed Jan 20, 2018
1 parent 5151202 commit cc117e7
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 43 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
ndpar_lib
=====

My Erlang/OTP library.
This repository is a collection of algorithms and exercises from the following books

- [Cryptography Engineering](https://www.schneier.com/books/cryptography_engineering/) by Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
- [Erlang and OTP in Action](https://www.manning.com/books/erlang-and-otp-in-action) by Martin Logan, Eric Merritt, and Richard Carlsson
- [Erlang Programming](http://shop.oreilly.com/product/9780596518189.do) by Francesco Cesarini and Simon Thompson
- [Introduction to Algorithms](https://mitpress.mit.edu/books/introduction-algorithms) by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein
- [Programming Erlang](https://pragprog.com/book/jaerlang2/programming-erlang) (1st and 2nd editions) by Joe Armstrong

Build
-----
Expand All @@ -14,3 +20,7 @@ Test
$ rebar3 eunit
$ rebar3 dialyzer

Documentation
-----

$ rebar3 edoc
42 changes: 27 additions & 15 deletions src/bin.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%
% Various functions to work on binaries.
%
%%
%% @doc Various functions to work on binaries.
%%
-module(bin).
-export([integer_to_bitstring/1]).
-export([lxor/1, lxor/2]).
Expand All @@ -9,6 +9,14 @@
-export([term_to_packet/1, packet_to_term/1]).


%%
%% @doc Returns a bitstring representation of the
%% given integer with leading zeroes removed.
%%
%% E.g. `<<2#1100:4>> = bin:integer_to_bitstring(12).'
%%
%% @see binary:encode_unsigned/1.
%%
-spec integer_to_bitstring(non_neg_integer()) -> binary().

integer_to_bitstring(Int) -> trim_bitstring(binary:encode_unsigned(Int)).
Expand All @@ -17,37 +25,41 @@ trim_bitstring(<<>>) -> <<>>;
trim_bitstring(<<1:1, _/bitstring>> = B) -> B;
trim_bitstring(<<0:1, B/bitstring>>) -> trim_bitstring(B).


% Left XOR.
% E.g. ABCDEF xor 1234 = B9F9
%%
%% @doc Left XOR.
%%
%% E.g. `<<16#B9F9:16>> = bin:lxor(<<16#ABCDEF:24>>, <<16#1234:16>>).'
%%
-spec lxor(binary(), binary()) -> binary().

lxor(X, Y) ->
Length = min(size(X), size(Y)),
crypto:exor(binary:part(X, 0, Length), binary:part(Y, 0, Length)).

% Left XOR
% Can be used from escript/shell.
%%
%% @doc Left XOR.
%% Can be used from escript or shell.
%%
-spec lxor([string()]) -> string().

lxor([H | T]) ->
F = fun(X, Acc) -> lxor(hexstr_to_bin(X), Acc) end,
bin_to_hexstr(lists:foldl(F, hexstr_to_bin(H), T)).

%
% Converts hexadecimal string to binary.
% The string length is expected to be even.
%
%%
%% @doc Converts hexadecimal string to binary.
%% The string length is expected to be even.
%%
-spec hexstr_to_bin(string()) -> binary().

hexstr_to_bin(String) ->
0 = length(String) rem 2,
<<1:8, Bin/binary>> = binary:encode_unsigned(list_to_integer([$1 | String], 16)),
Bin.

%
% Converts binary to hexadecimal string.
%
%%
%% @doc Converts binary to hexadecimal string.
%%
-spec bin_to_hexstr(binary()) -> string().

bin_to_hexstr(Bin) ->
Expand Down
14 changes: 7 additions & 7 deletions src/life_async_grid.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
%%% This implementation can be run step by step, controlled from
%%% the shell, in which case it preserves the classic game behaviour.
%%% Or it can be run completely asynchronously until it's stopped by
%%% `stop` message. In this case the behaviour of the game is
%%% 'stop' message. In this case the behaviour of the game is
%%% eventually consistent, meaning that at any particular point
%%% there might be cells on the grid from different generations,
%%% which you wouldn't expect in the classic game. However,
%%% since cells "synchronize" with each other, the results of the
%%% async game "on average" will be the same as in the classic one.
%%%
%%% In either case, the default state of the grid can be examined
%%% by running `snapshot` command.
%%% by running 'snapshot' command.
%%%
%%% To run the game forever, uncomment line 153.
%%%
Expand Down Expand Up @@ -69,24 +69,24 @@ new_grid(Size) ->
end,
new_grid(), cartesian_plane(Size)).

%% @doc Sends `connect` message to all cells.
%% @doc Sends 'connect' message to all cells.
%% It's done once during the initialization of the game.
%% Upon receiving this message, cells will discover their
%% neighbours and save reference to them.
connect_all(Grid) ->
ok = send(Grid, coordinates(Grid), {connect, Grid}).

%% @doc Sends `alive` message to specific cells.
%% @doc Sends 'alive' message to specific cells.
%% Upon receiving this message, cells will change their state to alive.
make_alive(Coords, Grid) ->
ok = send(Grid, Coords, alive).

%% @doc Sends `start` message to all cells.
%% @doc Sends 'start' message to all cells.
%% That will initiate the first step of the game.
start(Grid) ->
ok = send(Grid, coordinates(Grid), start).

%% @doc Sends `current_status` message to all cells, requesting
%% @doc Sends 'current_status' message to all cells, requesting
%% their status. Blocks until receiving responses from all cells.
%% Returns coordinates of all live cells together with their
%% generation numbers.
Expand All @@ -101,7 +101,7 @@ snapshot(Grid) ->
end
end, [], All).

%% @doc Sends `stop` message to all cells, forcing them to leave game.
%% @doc Sends 'stop' message to all cells, forcing them to leave game.
stop(Grid) ->
ok = send(Grid, coordinates(Grid), stop).

Expand Down
24 changes: 15 additions & 9 deletions src/maths.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%
%% Math functions missing in the standard math module.
%% @doc Math functions missing in the standard math module.
%%
-module(maths).
-author("Andrey Paramonov").
Expand All @@ -10,8 +10,10 @@

%%
%% @doc Extended Euclidean Algorithm to compute GCD.
%% This identity holds true: GCD(A, B) = A * U + B * V.
%%
-spec egcd(pos_integer(), pos_integer()) -> {pos_integer(), pos_integer(), pos_integer()}.
-spec egcd(A :: pos_integer(), B :: pos_integer()) ->
{GCD :: pos_integer(), U :: integer(), V :: integer()}.

egcd(A, B) when 0 < A, 0 < B -> egcd(A, B, 1, 0, 0, 1).

Expand All @@ -21,29 +23,32 @@ egcd(C, D, Uc, Vc, Ud, Vd) ->
egcd(D - Q * C, C, Ud - Q * Uc, Vd - Q * Vc, Uc, Vc).

%%
%% @doc Euclidean Algorithm to compute GCD.
%% @doc Returns the GCD of two positive integers.
%%
-spec gcd(pos_integer(), pos_integer()) -> pos_integer().

gcd(A, B) -> {GCD, _, _} = egcd(A, B), GCD.

%%
%% @doc Least common multiple.
%% @doc Returns the least common multiple (LCM) of two positive integers.
%%
-spec lcm(pos_integer(), pos_integer()) -> pos_integer().

lcm(A, B) -> A * B div gcd(A, B).

%%
%% @doc Floor of the logarithm base 2 of the given integer N.
%%
-spec ilog2(N :: pos_integer()) -> pos_integer().
-spec ilog2(pos_integer()) -> pos_integer().

ilog2(N) when 0 < N ->
B = bin:integer_to_bitstring(N),
bit_size(B) - 1.

%%
%% @doc Integer square root.
%% https://en.wikipedia.org/wiki/Integer_square_root#Using_bitwise_operations
%% Implemented using bitwise algorithm
%% (https://en.wikipedia.org/wiki/Integer_square_root#Using_bitwise_operations)
%%
-spec isqrt(non_neg_integer()) -> non_neg_integer().

Expand All @@ -65,7 +70,7 @@ isqrt_root(N, Shift, Root) ->
end.

%%
%% @doc mod that works properly on negative integers.
%% @doc Modulo operation that works properly on negative integers.
%%
-spec mod(integer(), pos_integer()) -> non_neg_integer().

Expand All @@ -80,7 +85,8 @@ mod(A, M) -> (A rem M + M) rem M.
%% number of arithmetic operations required is O(b) and
%% the total number of bit operations required is O(b^3).
%%
%% See also: crypto:mod_pow/3 and crypto:bytes_to_integer/1
%% @see crypto:mod_pow/3
%% @see crypto:bytes_to_integer/1
%%
-spec mod_exp(Base :: non_neg_integer(), Exp :: non_neg_integer(), Mod :: pos_integer()) -> non_neg_integer().

Expand Down Expand Up @@ -127,7 +133,7 @@ mod_linear_equation_solver_list(N, D, X0) ->
%%
%% @doc Integer power of another integer
%%
-spec pow(N :: integer(), E :: non_neg_integer()) -> integer().
-spec pow(N :: integer(), Exp :: non_neg_integer()) -> integer().

pow(_, 0) -> 1;
pow(N, E) -> N * pow(N, E - 1).
Expand Down
23 changes: 12 additions & 11 deletions src/rsa_private_key.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
%%
%% N.Ferguson, B.Schneier, T. Kohno. Cryptography Engineering.
%% Chapter 12.4.3. The Private Key.
%% @doc Restoring RSA private key from its parts.
%%
%% RSA private key consists of four integer values {p, q, t, d}.
%% The knowledge of any one of these values is sufficient to
Expand All @@ -10,23 +9,25 @@
%% t = (p - 1)(q - 1) / gcd(p - 1, q - 1).
%% d = e^-1 (mod t).
%%
-module(rsa_private_key).
-author("Andrey Paramonov").

%%
%% To play with the functions, the following commands may be useful
%% if you want to generate real private keys:
%%
%% To play with the functions in this module, the following commands
%% may be useful if you want to generate the real private keys:
%% ```
%% $ openssl genrsa -out private.pem 2048
%% $ openssl asn1parse -i -in private.pem
%% '''
%% @reference N.Ferguson, B.Schneier, T. Kohno. <em>Cryptography Engineering</em>.
%% Chapter 12.4.3. The Private Key.
%%
-module(rsa_private_key).
-author("Andrey Paramonov").

-export([factorize_from_d/3, factorize_from_t/2]).

%%
%% @doc If attacker knows d, she can find {p, q} using this method.
%%
-spec factorize_from_d(N :: pos_integer(), E :: pos_integer(), D :: pos_integer()) ->
{pos_integer(), pos_integer()} | error.
{P :: pos_integer(), Q :: pos_integer()} | error.

factorize_from_d(N, E, D) ->
factorize_from_d(N, E, D, 1).
Expand All @@ -41,7 +42,7 @@ factorize_from_d(N, E, D, Factor) ->
%% @doc If attacker knows t, she can find {p, q} using this method.
%%
-spec factorize_from_t(N :: pos_integer(), T :: pos_integer()) ->
{pos_integer(), pos_integer()} | error.
{P :: pos_integer(), Q :: pos_integer()} | error.

factorize_from_t(N, T) ->
case N div T of
Expand Down

0 comments on commit cc117e7

Please sign in to comment.