A re-implementation of the GNU program dc, in modular arithmetic.
As of right now, strings, arrays and macros aren't implemented.
The supported operations are:
<number>,_<number>: pushes the numbernumberonto the stack. If it is preceded by_, pushes the negative value for it.m: pops a value from the stack and sets it as the modulus for all subsequent operations; if set to 0 (default), then no modulus is applied. This number is referred to asmM: pushes onto the stack the value ofm%: pops a numberxfrom the stack and pushes backx mod m+: pops two numbersaandband pushes back(a + b) mod m(ora + bifm = 0)-: pops two numbersaandband pushes back(a - b) mod m(ora - bifm = 0)*: pops two numbersaandband pushes back(a * b) mod m(ora * bifm = 0)/: pops two numbersaandband pushes back(a / b) mod m(ora // bifm = 0); requires thatgcd(b, m)dividesa^: pops two numbersaandband pushes back(a ^ b) mod m(ora ^ bifm = 0; in that case,bmust be less thanULONG_MAX)C: pops two numbersaandband pushes backlcm(a, b)G: pops two numbersaandband pushes backgcd(a, b)d: duplicates the value on top of the stackz: pushes on the stack the current length of the stackv: pops a numberxfrom the stack and computes the modular square root ofx, see Modular square root for more information (Note: composite moduli and moduli congruent to 1 mod 8 haven't been implemented yet.)~: pops a numberxfrom the stack and pushes back-x mod m(ormifm = 0)f: prints the entirety of the stackp: prints the top value of the stackn: pops a number from the stack and prints it, without a newlinec: clears the stackr: swaps the position of the top two values of the stacks<r>: popsxfrom the stack and stores in on the top of the register<r>(overriding the previous value)S<r>: popsxfrom the stack and pushes it on top of the register<r>'s stack (shadowing the previous value)l<r>: pushes on the stack the top value of the register<r>L<r>: popsxfrom the stack of the register<r>and pushes it onto the stack (un-shadowing values below it)
Spaces are optional, except between numbers.
I really recommend reading through dc's documentation if you aren't somewhat familiar with it already.
To compile and use this software, you will need git, GNU Make, a C compiler and the GNU MP library (gmp on Arch Linux).
First, clone this repository, then compile it with make:
git clone https://github.com/adri326/mdc
cd mdc
makeThe final binary will be put in build/mdc.
You can copy it into a directory that is in your PATH to have the command mdc available everywhere.
Simply execute the mdc binary; it will then read input from stdin and print output to stdout.
If you aren't piping anything into mdc, then it will act as a kind of terminal; you may write and edit commands, and submit them by pressing enter.
To exit, press Ctrl+D to send the EoF character.
31m # Set the modulus to 31
10 # Push 10
2* p # Prints 20
2* p # Prints 40%31 = 9
4* p # Prints (9*4) % 31 = 5The following expression computes (23*(3*1+40))² - 2 mod 103:
103m
1 3* 40 + # (3*1 + 40)
23* 2^ # (23*(3*1+40))²
2- # (23*(3*1+40))² - 2
p # Prints 31The following encrypts and decrypts a message using RSA:
2010942103422233250095259520183 sp # p
3503815992030544427564583819137 sq # q
lplq*p sn # n
lp1-lq1-Cm # Compute λ(n) and use it as modulo
2 16^ 1+ d se # e = 2^16+1
1r/p sd # d = e^-1 mod λ(n)
lnm # Use n as modulo
36762444129608 le ^p # Encode the message with (n, e); here the message is the decimal version of "Hello!"
ld ^p # Decode the messageFor comparison, here is how you would have to do it using vanilla dc:
2010942103422233250095259520183 sp # p
3503815992030544427564583819137 sq # q
lplq*p sn # n
lp1- lq1- # Load p-1 and q-1
[dSarLa%d0<a]dsax+ # Compute gcd(p-1, q-1), thank you Wikipedia for the expression
lp1- lq1- *r/ sl # Compute λ(n) and store it
2 16^ 1+ d se # e = 2^16+1
lldsm le dsa1sv[dsb~rsqlbrldlqlv*-lvsdsvd0<x]dsxxldd[dlmr+]sx0>x p sd # Computes d = e^-1 mod λ(n), thanks Rosetta stone for this expression
36762444129608 le ln |p # Encode the message with (n, e); here the message is the decimal version of "Hello!"
ld ln |p # Decode the messageThis software is provided as-is, there is no warranty, to the extent permitted by law. See LICENSE.md for more detail.
This software is not fit for cryptographic uses, use it at your own risk.