Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert AES-128-CTR to pre-parsed C++ circuit #171

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

kdrag0n
Copy link
Contributor

@kdrag0n kdrag0n commented Jul 22, 2022

  • Add support for loading and generating pre-parsed C++ code for BristolFashion circuits (mostly copied from BristolFormat)
  • Use a pre-parsed AES-128 circuit for AES_128_CTR_Calculator in order to improve initialization time, especially in environments where sscanf is relatively slow (45 -> 35 ms in a program that uses the AES_128_CTR_Calculator)

Mostly copied from the BristolFormat implementation.
This provides a considerable improvement in AES_128_CTR_Calculator's
initialization time, especially in environments where sscanf is
relatively slow.

Time in a program that uses AES_128_CTR_Calculator has decreased from
~45 to 35 ms.
@wangxiao1254
Copy link
Member

Thanks for your contribution. However, I'm not sure if it is a good idea to put aes_128.cpp as the source since it is essentially duplicated information with aes_128.txt.

There is a pre-parsed AES from https://github.com/emp-toolkit/emp-tool/blob/master/CMakeLists.txt#L17 already. What's the difference?

@kdrag0n
Copy link
Contributor Author

kdrag0n commented Jul 26, 2022

Thanks for your contribution. However, I'm not sure if it is a good idea to put aes_128.cpp as the source since it is essentially duplicated information with aes_128.txt.

I agree that the duplication isn't ideal, but I'm not sure what the alternative is. The txt.cpp file can be generated at compile-time with shell commands, but generating this is a bit more complicated and requires calling BristolFashion::to_file from C++.

There is a pre-parsed AES from https://github.com/emp-toolkit/emp-tool/blob/master/CMakeLists.txt#L17 already. What's the difference?

The txt.cpp + fmemopen approach is certainly faster than reading from a file, but in my testing, it's still considerably slower than this because the textual data is parsed with sscanf (character-by-character) every time AES_128_CTR_Calculator is initialized.

This pre-parsed circuit already has all the text parsed into numbers that are compiled into the library as constant data (similar to the output of BristolFormat::to_file) and offloads the cost of parsing to a one-time job, so the program never incurs the cost of sscanf. The cost can be significant in some slower environments.

Benchmarks of a program that uses AES_128_CTR_Calculator, before and after this change:

Host: 45 -> 35 ms
Slower environment: 350 -> 250 ms (mostly relevant here)

@wangxiao1254
Copy link
Member

The aes_128.txt.cpp does not need fmemopen right? the array is compiled to a binary statically.

@kdrag0n
Copy link
Contributor Author

kdrag0n commented Jul 27, 2022

The txt.cpp file looks like this:

#include "emp-tool/circuits/aes_128_ctr.h"
unsigned char emp_tool_circuits_files_bristol_fashion_aes_128_txt[] = {
  0x33, 0x36, 0x36, 0x36, 0x33, 0x20, 0x33, 0x36, 0x39, 0x31, 0x39, 0x0a,
  0x32, 0x20, 0x31, 0x32, 0x38, 0x20, 0x31, 0x32, 0x38, 0x20, 0x0a, 0x31,
  0x20, 0x31, 0x32, 0x38, 0x20, 0x0a, 0x0a, 0x32, 0x20, 0x31, 0x20, 0x31,
  0x32, 0x38, 0x20, 0x30, 0x20, 0x33, 0x33, 0x32, 0x35, 0x34, 0x20, 0x58,
  0x4f, 0x52, 0x0a, 0x32, 0x20, 0x31, 0x20, 0x31, 0x32, 0x39, 0x20, 0x31,
  0x20, 0x33, 0x33, 0x32, 0x35, 0x35, 0x20, 0x58, 0x4f, 0x52, 0x0a, 0x32,
  0x20, 0x31, 0x20, 0x31, 0x33, 0x30, 0x20, 0x32, 0x20, 0x33, 0x33, 0x32,
  0x35, 0x36, 0x20, 0x58, 0x4f, 0x52, 0x0a, 0x32, 0x20, 0x31, 0x20, 0x31,

It's compiled into the binary, but the embedded data is the content of aes_128.txt — still in textual form. fmemopen is used to open a virtual FILE pointing to this data so the text can be parsed with fscanf:

FILE * circuit_file = fmemopen(emp_tool_circuits_files_bristol_fashion_aes_128_txt,

(void)fscanf(f, "%d%d%d%d%s", &tmp, &gates[4*i], &gates[4*i+1], &gates[4*i+2], str);

@wangxiao1254
Copy link
Member

I see you are right! I think the best way is to modify the existing code so that the generated array in the current code base does not need parsing anymore, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants