A Proof of Concept implementation of the Advanced Rejection Sampling Algorithm for covert information leakage.
The project requires OpenSSL to build. On Ubuntu, you might need libssl-dev
package.
Run the install.sh
script (requires make
and gcc/clang
);
Next, build with cmake.
If you don't know how, you can use this (requires gcc/clang
and make
):
cmake -B build && cd build && make
or e.g. this for debug build (requires gcc
and Ninja
):
cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc -B ./build -G Ninja
cmake --build ./build --config Debug --target all --
If you want to link OpenSSL statically, use cmake
with -DUSE_STATIC_OPENSSL_LIBS=True
and set the location of OpenSSL include directory and the libcrypto library in CMakeLists.txt (it is currently set to standard locations in Arch linux).
You can find the "OPENSSL_ROOT_DIR" with:
openssl version -d
and the "OPENSSL_CRYPTO_LIBRARY" with:
find / -name "libcrypto*" 2>/dev/null
After setting the location, run:
cmake -B build -DUSE_STATIC_OPENSSL_LIBS=True && cd build && make
To use the watermarking tool, first build the binaries. Then, you can use:
./bin/watermarking help
to show options. In general, usage looks like this:
To generate a lookup table run the watermarking
binary with g
option:
watermarking [-v] g[enerate_lut] '/save/path' '/path/to/enc_key.pub' (m) [C] 'dual_key'
[-v]
: [OPTIONAL] verbose mode.[-vv]
is debug mode'/save/path'
: Save location of the generated lookup table.'/path/to/enc_key.pub
': Path to PEM-encoded ECDSA public key used to encrypt the anamorphic message(m)
: Number of bits to be encrypted (width of the anamorphic channel). 0 < m < 32[C]
: [OPTIONAL] Number of records in a row of the lookup table. Default is 5'dual_key'
: String used as a dual key to encrypt the anamorphic message.
./bin/watermarking -v generate_lut lut.out ./keys/ec-secp256k1-pub-key_enc.pem 8 5 'Secret dual key'
The serialized lookup table is required for anamorphic signing.
To sign a message and encrypt a watermark, use the watermarking
binary with option s
:
watermarking [-v] s[ign] '/sign.bin' '/path/to/lut' '/path/to/sign_key.priv' '/path/to/enc_key.pub' '/path/to/sign_msg.txt' 'watermark' 'dual_key' ['delta']
[-v]
: [OPTIONAL] verbose mode.[-vv]
is debug mode'/sign.bin'
: Save location of the generated signature'/path/to/lut'
: Path to a lookup table generated by the commandg
'/path/to/sign_key.priv'
: Path to PEM-encoded ECDSA signing key used to sign a message'/path/to/enc_key.pub'
: Path to PEM-encoded ECDSA public key used to encrypt the'watermark'
'/path/to/sign_msg.txt'
: Path to file containing message to be signed with private key (can be binary)'watermark'
: Message to be encrypted inside of the signature'dual_key'
: String used as a dual key to encrypt the 'watermark'['delta']
: [OPTIONAL] Unique public string to be used for encryption. Default is the timestamp of the signature.
./bin/watermarking s sign.bin lut.out ./keys/ec-secp256k1-priv-key.pem ./keys/ec-secp256k1-pub-key_enc.pem msg.test 'bb' 'Secret dual key' 'Some unique public string 1'
The signature will verify with 'normal' openssl verification as well. You can check it with command like this:
$ openssl dgst -sha3-256 -verify ./keys/ec-secp256k1-pub-key.pem -signature sign.bin msg.test
Verified OK
To verify the signature and decrypt the anamorphic message, run the watermarking
binary with option d
:
watermarking [-v] d[ecrypt] '/path/to/sign_key.pub' '/path/to/enc_key.priv' '/path/to/sig.bin' '/path/to/sign_msg.txt' (m) 'dual_key' 'delta'
[-v]
: [OPTIONAL] verbose mode.[-vv]
is debug mode'/path/to/sign_key.pub'
: Path to PEM-encoded ECDSA signing public key used to verify the'message_to_verify'
'/path/to/enc_key.priv'
: Path to PEM-encoded ECDSA private key used to decrypt the anamorphic message'/path/to/sig.bin'
: Path to file containing the signature to verify and decrypt from'/path/to/sign_msg.txt'
: Path to file containing message to be verified with the public key\(m)
: Number of bits to be decrypted (width of the anamorphic channel). 0 < m < 32'dual_key'
: String used as a dual key to decrypt the anamorphic message'delta'
: Public string to be used for decryption. By default its the timestamp of the signature
./bin/watermarking d ./keys/ec-secp256k1-pub-key.pem ./keys/ec-secp256k1-priv-key_enc.pem sign.bin msg.test 8 'Secret dual key' 'Some unique public string 1'
The recovered message should be the same as provided in the signing step. If its not, check if you're using the same dual_key
, delta
, m
, lookup table, keys and of course sign message!
To run benchmarks, first build all binaries and cd into the benchmarks folder:
cd benchmarks
Then, run all of the benchmarks to generate output csv files:
./benchmark -ecdsa && ./benchmark -rs && ./benchmark -as 0 5 && ./benchmark -as 8 0 && ./benchmark -lut
To visualize benchmark results, run the python script (requires matplotlib
and numpy
):
python visualize_benchmarks.py
To run tests, first build the binaries and cd into the bin folder
cd ./bin
Then run the test binaries with no arguments (they can take some time):
./test*
Make sure that the keys are generated in the {root-git}/keys
directory!