Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); aes: soft `hazmat` backend by tarcieri · Pull Request #268 · RustCrypto/block-ciphers · GitHub
Skip to content

aes: soft hazmat backend - #268

Merged
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend
May 31, 2021
Merged

aes: soft hazmat backend#268
tarcieri merged 1 commit into
masterfrom
aes/soft-hazmat-backend

Conversation

@tarcieri

@tarcieritarcieri commented May 30, 2021

Copy link
Copy Markdown
Member

The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

As an initial attempt I tried to implement the hazmat::cipher_round function on top of the 64-bit fixsliced backend.

It's not quite working but it seems close. I'm not quite sure what I'm missing:

---- cipher_round_fips197_vectors stdout ----
thread 'cipher_round_fips197_vectors' panicked at 'assertion failed: `(left == right)`
left: `[137, 221, 28, 235, 133, 83, 202, 111, 45, 21, 79, 211, 203, 19, 139, 235]`,
right: `[137, 216, 16, 232, 133, 90, 206, 104, 45, 24, 67, 216, 203, 18, 143, 228]`', aes/tests/hazmat.rs:82:9

(left is actual, right is expected from the test vector)

The deltas in bits look like this (broken down by AES word):

0b0, 0b101, 0b1100, 0b11,
0b0, 0b1001, 0b100, 0b111,
0b0, 0b1101, 0b1100, 0b1011,
0b0, 0b1, 0b100, 0b1111

Unfortunately I can't directly compare to FIPS 197 step-by-step due to the key schedule being bitsliced and reordered.

@tarcieri

tarcieri commented May 30, 2021

Copy link
Copy Markdown
MemberAuthor

@peterdettman I don't suppose you have any insights here?

For context the intended use case here is Deoxys, or any other construction built on the raw AES round function.

@peterdettman

peterdettman commented May 31, 2021

Copy link
Copy Markdown
Contributor

@tarcieri Maybe I can take a closer look tomorrow, but if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it). Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

Edit: Oh I see it's a supplied round key. Then keep sub_bytes_nots and just use the method order above I think. (the way you have it currently, the round key hasn't been prepared with an inv_shift_rows_1 call).

@tarcieri

tarcieri commented May 31, 2021

Copy link
Copy Markdown
MemberAuthor

if it's using the existing key schedule I guess the sub_bytes_nots is the problem (remove it).

It's not. The goal is to support an AES-NI like API which can work with the standard FIPS 197-style key schedule (edit: or more specifically in the immediate intended use case, Deoxys's key schedule). We have backends working on AES-NI and the ARMv8 Cryptography Extensions. That said...

Although a more natural way to write the round function would be sub_bytes/shift_rows_1/mix_columns_0/add_round_key (this will also be the fastest).

I swear I tried this before, but if I do that with the inclusion of sub_bytes_nots, i.e.

  • sub_bytes
  • sub_bytes_nots
  • shift_rows_1
  • mix_columns_0
  • add_round_key

...it works! 🎉

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch 2 times, most recently from 5cfe35f to f831fbeCompareMay 31, 2021 16:42
@tarcieri

Copy link
Copy Markdown
MemberAuthor

Update: I now have all 4 operations (cipher, equiv inverse cipher, mix columns, and inv mix columns) working on the 64-bit backend.

Gonna do the 32-bit one.

Something else we should definitely consider, especially for performance, is a ParBlocks-based API which accepts an array of round keys. I assume that's useful in Deoxys @zer0x64?

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from f831fbe to 38439acCompareMay 31, 2021 16:45
@zer0x64

Copy link
Copy Markdown

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

@tarcieri

Copy link
Copy Markdown
MemberAuthor

You mean an API that can do multiple rounds instead of a single one? I think that would help the compiler a lot with auto-vectorization, especially if it's able to unroll the loop and reuse the SIMD registers instead of reload/saving it at each iteration.

Yep. Each invocation to the soft backend is actually computing 4 blocks in parallel on 64-bit archs (2 blocks on 32-bit ones), so it's pretty wasteful to shoehorn a single block API on top of it.

I can take a crack at adding a parallel API after I get an initial PoC working.

Another thing we might need to consider is dynamic AES-NI detection, although I'm not sure the best way to do it.

It's already implemented, and works portably across x86(-64) and ARMv8:

https://github.com/RustCrypto/block-ciphers/blob/master/aes/src/hazmat.rs#L47-L55

@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 38439ac to 4cbc4f0CompareMay 31, 2021 16:59
The `hazmat` API provides access to the raw AES cipher round, equivalent
inverse cipher round, mix columns, and inverse mix column operations.
This commit wires up support in the "soft" backend (or more
specifically, both the 32-bit and 64-bit fixsliced backends).
It would benefit from a parallel API instead of what's currently
provided, however that's left for future work.
@tarcieri
tarcieriforce-pushed the aes/soft-hazmat-backend branch from 4cbc4f0 to 29b1bb6CompareMay 31, 2021 17:02
@tarcieritarcieri changed the title [WIP] aes: soft hazmat backendaes: soft hazmat backendMay 31, 2021
@tarcieri
tarcieri marked this pull request as ready for review May 31, 2021 17:06
@tarcieri
tarcieri merged commit 758169d into masterMay 31, 2021
@tarcieri
tarcieri deleted the aes/soft-hazmat-backend branch May 31, 2021 17:06
@zer0x64

Copy link
Copy Markdown

Not sure how using 4 parallel blocks would be useful for Deoxys, as each blocks uses a different set of round keys(the block number is used in the key schedule)

@tarcieri

Copy link
Copy Markdown
MemberAuthor

In a prospective API for this, you'd pass in an array of round keys and an array of blocks, and the parallel API could apply a particular round key to a particular block.

I can open a PR for it and we can discuss.

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri Note that there's no real reason to bitslice the round key here, instead it could be applied after the inv_bitslice of the state (and then only needed for the single output block).

@peterdettman

Copy link
Copy Markdown
Contributor

@tarcieri (inv_)mix_columns(_0) could also get non-bitsliced implementations for these, if/when it matters.

@tarcieri

tarcieri commented Jun 1, 2021

Copy link
Copy Markdown
MemberAuthor

I'm just about to open a follow-up which adds parallelism and does a bit of cleanup including avoiding bitslicing the round keys. Edit: opened #269.

Not terribly worried about putting too much effort into this API for now. I'd just like to get it PoC'd and working.

In the future, however, it might be interesting to try to use an API like this as the core of the overall implementation, which would get rid of a lot of redundant boilerplate that presently exists in the Aes128/Aes192/Aes256 and their associated trait impls.

This was referenced Jun 1, 2021
Sign up for freeto 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.

3 participants

@tarcieri@peterdettman@zer0x64