-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
armv7m: chacha common, add missing files
- Loading branch information
1 parent
793b774
commit 5a5ed3d
Showing
4 changed files
with
315 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
require "chacha_state.jinc" | ||
require "chacha_store.jinc" | ||
require "chacha_core.jinc" |
160 changes: 160 additions & 0 deletions
160
src/crypto_stream/chacha/common/armv7m/ref/chacha_core.jinc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
// the following implementation requires: | ||
// - (even) param int CHACHA_ROUNDS; | ||
// - inline fn __init_ref(reg u64 nonce key) -> stack u32[16] (check chacha_state.jinc) | ||
// - inline fn __increment_counter_ref(stack u32[16] state) -> stack u32[16] (check chacha_state.jinc) | ||
|
||
fn _copy_state_ref(reg ptr u32[16] k st) -> reg ptr u32[16] | ||
{ | ||
reg u32 i t; | ||
|
||
i = 0; | ||
while(i < 16) | ||
{ t = st[(int)i]; | ||
k[(int)i] = t; | ||
i += 1; | ||
} | ||
|
||
return k; | ||
} | ||
|
||
inline fn __line_ref(reg ptr u32[16] k, inline int a b c r) -> reg ptr u32[16] | ||
{ | ||
reg u32 ka kb kc; | ||
|
||
ka = k[a]; | ||
kb = k[b]; | ||
kc = k[c]; | ||
|
||
ka += kb; | ||
kc ^= ka; | ||
kc = #ROR(kc, (32-r)); | ||
|
||
k[a] = ka; | ||
k[c] = kc; | ||
|
||
return k; | ||
} | ||
|
||
inline fn __quarter_round_ref(reg ptr u32[16] k, inline int a b c d) -> reg ptr u32[16] | ||
{ | ||
k = __line_ref(k, a, b, d, 16); | ||
k = __line_ref(k, c, d, b, 12); | ||
k = __line_ref(k, a, b, d, 8); | ||
k = __line_ref(k, c, d, b, 7); | ||
return k; | ||
} | ||
|
||
inline fn __column_round_ref(reg ptr u32[16] k) -> reg ptr u32[16] | ||
{ | ||
k = __quarter_round_ref(k, 0, 4, 8, 12); | ||
k = __quarter_round_ref(k, 1, 5, 9, 13); | ||
k = __quarter_round_ref(k, 2, 6, 10, 14); | ||
k = __quarter_round_ref(k, 3, 7, 11, 15); | ||
return k; | ||
} | ||
|
||
inline fn __diagonal_round_ref(reg ptr u32[16] k) -> reg ptr u32[16] | ||
{ | ||
k = __quarter_round_ref(k, 0, 5, 10, 15); | ||
k = __quarter_round_ref(k, 1, 6, 11, 12); | ||
k = __quarter_round_ref(k, 2, 7, 8, 13); | ||
k = __quarter_round_ref(k, 3, 4, 9, 14); | ||
return k; | ||
} | ||
|
||
// TODO: write compact version of this: line_ref args from inline to reg | ||
inline fn __double_round_ref(reg ptr u32[16] k) -> reg ptr u32[16] | ||
{ | ||
k = __column_round_ref(k); | ||
k = __diagonal_round_ref(k); | ||
return k; | ||
} | ||
|
||
fn _rounds_ref(reg ptr u32[16] k) -> reg ptr u32[16] | ||
{ | ||
reg bool zf; | ||
reg u32 c; | ||
|
||
c = (CHACHA_ROUNDS/2); | ||
while | ||
{ k = __double_round_ref(k); | ||
_, zf, _, _, c = #SUBS(c, 1); | ||
} (!zf) | ||
|
||
return k; | ||
} | ||
|
||
fn _sum_states_ref(reg ptr u32[16] k st) -> reg ptr u32[16] | ||
{ | ||
reg u32 i tk tst; | ||
|
||
i = 0; | ||
while(i < 16) | ||
{ | ||
tk = k[(int)i]; | ||
tst = st[(int)i]; | ||
tk += tst; | ||
k[(int)i] = tk; | ||
|
||
i += 1; | ||
} | ||
|
||
return k; | ||
} | ||
|
||
inline fn __chacha_xor_ref(reg u32 output plain len nonce key) | ||
{ | ||
stack u32[16] k st; | ||
reg ptr u32[16] kp stp; | ||
|
||
kp = k; | ||
stp = st; | ||
|
||
nonce = nonce; // allow register swap | ||
key = key; // same. | ||
|
||
stp = _init_ref(stp, nonce, key); | ||
|
||
while (len >= 64) | ||
{ kp = _copy_state_ref(kp, stp); | ||
kp = _rounds_ref(kp); | ||
output, plain, len = __sum_states_store_xor_ref(output, plain,len, kp, stp); | ||
stp = __increment_counter_ref(stp); | ||
} | ||
|
||
if(len > 0) | ||
{ kp = _copy_state_ref(kp, stp); | ||
kp = _rounds_ref(kp); | ||
kp = _sum_states_ref(kp, stp); | ||
__store_xor_last_ref(output, plain, len, kp); | ||
} | ||
} | ||
|
||
inline fn __chacha_ref(reg u32 output len nonce key) | ||
{ | ||
stack u32[16] k st; | ||
reg ptr u32[16] kp stp; | ||
|
||
kp = k; | ||
stp = st; | ||
|
||
nonce = nonce; // allow register swap | ||
key = key; // same. | ||
|
||
stp = _init_ref(stp, nonce, key); | ||
|
||
while (len >= 64) | ||
{ kp = _copy_state_ref(kp, stp); | ||
kp = _rounds_ref(kp); | ||
output, len = __sum_states_store_ref(output, len, kp, stp); | ||
stp = __increment_counter_ref(stp); | ||
} | ||
|
||
if(len > 0) | ||
{ kp = _copy_state_ref(kp, stp); | ||
kp = _rounds_ref(kp); | ||
kp = _sum_states_ref(kp, stp); | ||
__store_last_ref(output, len, kp); | ||
} | ||
} | ||
|
56 changes: 56 additions & 0 deletions
56
src/crypto_stream/chacha/common/armv7m/ref/chacha_state.jinc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
|
||
u32[4] CHACHA_SIGMA = { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 }; | ||
|
||
// nonce : 8 bytes | ||
// key : 32 bytes | ||
// counter : 8 bytes (starts at 0) | ||
fn _init_ref(reg ptr u32[16] st, reg u32 nonce key) -> reg ptr u32[16] | ||
{ | ||
// TODO: compress this function | ||
|
||
reg ptr u32[4] sigma; | ||
reg u32 t; | ||
inline int i; | ||
|
||
sigma = CHACHA_SIGMA; | ||
for i=0 to 4 | ||
{ t = sigma[i]; | ||
st[i] = t; } | ||
|
||
// reads 8 u32 from pointer key | ||
for i=0 to 8 | ||
{ t = (u32)[key + 4*i]; | ||
st[4+i] = t; } | ||
|
||
// 64-bit counter | ||
t = 0; | ||
st[12] = t; | ||
st[13] = t; | ||
|
||
// nonce | ||
t = (u32)[nonce + 0]; | ||
st[14] = t; | ||
t = (u32)[nonce + 4]; | ||
st[15] = t; | ||
|
||
return st; | ||
} | ||
|
||
// TODO: double check here: 64 bit counter | ||
// increments 64-bit counter | ||
inline fn __increment_counter_ref(reg ptr u32[16] st) -> reg ptr u32[16] | ||
{ | ||
reg bool cf; | ||
reg u32 l h; | ||
|
||
l = st[12]; | ||
h = st[13]; | ||
|
||
_, _, cf, _, l = #ADDS(l, 1); | ||
h = #ADDcc(h, 1, cf, h); | ||
|
||
st[12] = l; | ||
st[13] = h; | ||
|
||
return st; | ||
} |
96 changes: 96 additions & 0 deletions
96
src/crypto_stream/chacha/common/armv7m/ref/chacha_store.jinc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
|
||
// store 'xor' //////////////////////////////////////////////////////////////// | ||
|
||
inline fn __update_ptr_xor_ref(reg u32 output plain len, inline int n) -> reg u32, reg u32, reg u32 | ||
{ | ||
output += n; | ||
plain += n; | ||
len -= n; | ||
return output, plain, len; | ||
} | ||
|
||
inline fn __sum_states_store_xor_ref( | ||
reg u32 output plain len, | ||
reg ptr u32[16] k st) | ||
-> | ||
reg u32, reg u32, reg u32 | ||
{ | ||
reg u32 i t s v; | ||
|
||
i = 0; | ||
while(i < 16) | ||
{ t = k[(int)i]; | ||
s = st[(int)i]; | ||
v = (u32)[plain + 4*i]; | ||
t += s; | ||
t ^= v; | ||
(u32)[output + 4*i] = t; | ||
i += 1; | ||
} | ||
|
||
output, plain, len = __update_ptr_xor_ref(output, plain, len, 64); | ||
|
||
return output, plain, len; | ||
} | ||
|
||
|
||
// len bytes | ||
inline fn __store_xor_last_ref(reg u32 output plain len, reg ptr u32[16] k) | ||
{ | ||
reg u32 i t v; | ||
|
||
i = 0; | ||
while(i < len) | ||
{ t = (32u)k[u8 (int)i]; | ||
v = (32u)(u8)[plain + i]; | ||
t ^= v; | ||
(u8)[output + i] = t; | ||
i += 1; | ||
} | ||
} | ||
|
||
// store ////////////////////////////////////////////////////////////////////// | ||
|
||
inline fn __update_ptr_ref(reg u32 output len, inline int n) -> reg u32, reg u32 | ||
{ | ||
output += n; | ||
len -= n; | ||
return output, len; | ||
} | ||
|
||
inline fn __sum_states_store_ref( | ||
reg u32 output len, | ||
reg ptr u32[16] k st) | ||
-> | ||
reg u32, reg u32 | ||
{ | ||
reg u32 i t s; | ||
|
||
i = 0; | ||
while(i < 16) | ||
{ t = k[(int)i]; | ||
s = st[(int)i]; | ||
t += s; | ||
[output + 4*i] = t; | ||
i += 1; | ||
} | ||
|
||
output, len = __update_ptr_ref(output, len, 64); | ||
|
||
return output, len; | ||
} | ||
|
||
// len bytes | ||
inline fn __store_last_ref(reg u32 output len, reg ptr u32[16] k) | ||
{ | ||
reg u32 i t; | ||
|
||
i = 0; | ||
while(i < len) | ||
{ t = (32u)k[u8 (int)i]; | ||
(u8)[output + i] = t; | ||
i += 1; | ||
} | ||
} | ||
|
||
|