-
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.
Merge pull request #101 from potsrevennil/feature/frodokem
frodo: add frodo640shake and frodo976shake reference implementation
- Loading branch information
Showing
22 changed files
with
3,771 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,76 @@ | ||
fn __encode(reg ptr u16[NBAR * NBAR]out, reg ptr u8[EXTRACTED_BITS * NBAR * NBAR / 8] in) -> stack u16[NBAR * NBAR] { | ||
inline int k; | ||
reg u64 i j t tmp tmp2 mask offset; | ||
|
||
mask = (1 << EXTRACTED_BITS) - 1; | ||
|
||
i = 0; | ||
while (i < NBAR) { | ||
tmp = 0; | ||
|
||
offset = i * EXTRACTED_BITS; | ||
for k = 0 to EXTRACTED_BITS { | ||
tmp2 = (64u)in[offset + k]; | ||
tmp2 <<= 8 * k; | ||
tmp |= tmp2; | ||
} | ||
|
||
j = 0; | ||
while (j < 8) { | ||
t = tmp; | ||
t &= mask; | ||
t <<= D - EXTRACTED_BITS; | ||
offset = #LEA(i*NBAR+j); | ||
out[offset] = (16u)t; | ||
tmp >>= EXTRACTED_BITS; | ||
|
||
j += 1; | ||
} | ||
|
||
i += 1; | ||
} | ||
|
||
return out; | ||
} | ||
|
||
fn __decode(reg ptr u8[EXTRACTED_BITS * NBAR] out, reg ptr u16[NBAR * NBAR] in) -> stack u8[EXTRACTED_BITS * NBAR] { | ||
reg u32 tmplong tmp mask d; | ||
reg u64 i j offset; | ||
|
||
d = 1 << (D - EXTRACTED_BITS - 1); | ||
mask = (1 << EXTRACTED_BITS) - 1; | ||
|
||
out = out; | ||
in = in; | ||
|
||
i = 0; | ||
while (i < NBAR) { | ||
tmplong = 0; | ||
|
||
j = 0; | ||
while (j < 8) { | ||
offset = #LEA(i * NBAR + 7); | ||
offset -= j; | ||
tmp = (32u)in[offset]; | ||
tmp += d; | ||
tmp >>= D - EXTRACTED_BITS; | ||
tmp &= mask; | ||
|
||
tmplong <<= EXTRACTED_BITS; | ||
tmplong |= tmp; | ||
j += 1; | ||
} | ||
|
||
j = 0; | ||
offset = i*EXTRACTED_BITS; | ||
while (j < EXTRACTED_BITS) { | ||
out[offset] = (8u)tmplong; | ||
tmplong >>= 8; | ||
j += 1; | ||
offset += 1; | ||
} | ||
i += 1; | ||
} | ||
|
||
return out; | ||
} |
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,108 @@ | ||
fn __matrix_add(reg ptr u16[NBAR * NBAR] a b) -> stack u16[NBAR * NBAR] { | ||
reg u64 i; | ||
reg u16 tmp; | ||
|
||
i = 0; | ||
while (i < NBAR * NBAR) { | ||
tmp = a[i]; | ||
tmp += b[i]; | ||
tmp &= (1 << D) - 1; | ||
a[i] = tmp; | ||
i += 1; | ||
} | ||
|
||
return a; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
// a = b - a | ||
fn __matrix_sub(reg ptr u16[NBAR * NBAR] a b) -> stack u16[NBAR * NBAR] { | ||
reg u64 i; | ||
reg u16 tmp; | ||
|
||
i = 0; | ||
while (i < NBAR * NBAR) { | ||
tmp = b[i]; | ||
tmp -= a[i]; | ||
tmp &= (1 << D) - 1; | ||
a[i] = tmp; | ||
i += 1; | ||
} | ||
|
||
return a; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
fn __ct_verify_NNBAR(reg ptr u16[NNBAR] a b) -> stack u8 { | ||
reg u64 i; | ||
reg u16 ac tmp; | ||
reg u8 r; | ||
|
||
i = 0; | ||
ac = 0; | ||
while (i < NNBAR) { | ||
tmp = a[(int) i]; | ||
tmp ^= b[(int)i]; | ||
ac |= tmp; | ||
i += 1; | ||
} | ||
|
||
tmp = ac * -1; | ||
ac |= tmp; | ||
ac >>= 15; | ||
ac *= (-1); | ||
|
||
r = (8u)ac; | ||
|
||
return r; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
fn __ct_verify_NBAR2(reg ptr u16[NBAR * NBAR] a b) -> stack u8 { | ||
reg u64 i; | ||
reg u16 ac tmp; | ||
reg u8 r; | ||
|
||
i = 0; | ||
ac = 0; | ||
while (i < NBAR * NBAR) { | ||
tmp = a[(int) i]; | ||
tmp ^= b[(int)i]; | ||
ac |= tmp; | ||
i += 1; | ||
} | ||
|
||
tmp = ac * -1; | ||
ac |= tmp; | ||
ac >>= 15; | ||
ac *= (-1); | ||
|
||
r = (8u) ac; | ||
|
||
return r; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
fn __ct_select(reg ptr u8[BYTES_SEC] out a b, reg u8 selector) -> stack u8[BYTES_SEC] { | ||
reg u64 i; | ||
|
||
reg u8 n_selector tmp; | ||
|
||
n_selector = selector; | ||
n_selector ^= 0xFF; | ||
|
||
i = 0; | ||
while (i < BYTES_SEC) { | ||
tmp = a[i]; | ||
tmp &= n_selector; | ||
out[i] = tmp; | ||
|
||
tmp = b[i]; | ||
tmp &= selector; | ||
out[i] |= tmp; | ||
|
||
i += 1; | ||
} | ||
|
||
return out; | ||
} |
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,191 @@ | ||
from Jade require "crypto_kem/frodo/common/amd64/ref/shake128.jinc" | ||
|
||
#[returnaddress="stack"] | ||
fn __AS_plus_E(reg ptr u16[NNBAR] B, reg ptr u8[BYTES_SEED_A]seedA, reg ptr u16[NNBAR] S E) -> stack u16[NNBAR] { | ||
stack ptr u16[NNBAR] s_B; | ||
stack u16[N] A_row; | ||
stack ptr u8[BYTES_SEED_A] s_seedA; | ||
stack ptr u16[NNBAR] s_S s_E; | ||
stack u8[2 + BYTES_SEED_A] b; | ||
|
||
reg u64 j k; stack u64 s_j s_k; | ||
reg u16 tmp ac; | ||
inline int i l; | ||
|
||
s_B = B; s_S = S; s_E = E; | ||
|
||
// copy seedA | ||
for i = 0 to BYTES_SEED_A { | ||
b[i + 2] = seedA[i]; | ||
} | ||
s_seedA = seedA; | ||
|
||
// first set B = E | ||
B = s_B; E = s_E; | ||
|
||
j = 0; | ||
while (j < NNBAR) { | ||
for l = 0 to 4 { | ||
B[(int)j + l] = E[(int)j + l]; | ||
} | ||
j += 4; | ||
} | ||
|
||
s_B = B; s_E = E; | ||
|
||
// calculate A and B += A * S | ||
b[u16 0] = 0; | ||
k = 0; | ||
|
||
while (b[u16 0] < N) { | ||
s_j = j; s_k = k; s_S = S; s_B = B; | ||
A_row = __shake128_gen_A(A_row, b); | ||
j = s_j; k = s_k; S = s_S; B = s_B; | ||
|
||
for i = 0 to NBAR { | ||
ac = 0; | ||
j = 0; | ||
|
||
// A_row * S_T_row | ||
while (j < N) { | ||
tmp = A_row[(int)j]; | ||
tmp *= S[i * N + (int)j]; | ||
ac += tmp; | ||
j += 1; | ||
} | ||
|
||
B[(int)k + i] += ac; | ||
} | ||
k += NBAR; | ||
|
||
b[u16 0] += 1; | ||
} | ||
|
||
return B; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
fn __SA_plus_E(reg ptr u16[NNBAR] B, reg ptr u8[BYTES_SEED_A]seedA, reg ptr u16[NNBAR] S E) -> stack u16[NNBAR] { | ||
stack ptr u16[NNBAR] s_B; | ||
stack u16[N] A_row; | ||
stack ptr u8[BYTES_SEED_A] s_seedA; | ||
stack ptr u16[NNBAR] s_S s_E; | ||
stack u8[2 + BYTES_SEED_A] b; | ||
|
||
reg u64 j k; stack u64 s_j s_k; | ||
reg u16 tmp s; | ||
inline int l; | ||
|
||
// copy seedA | ||
for l = 0 to BYTES_SEED_A { | ||
b[l + 2] = seedA[l]; | ||
} | ||
s_seedA = seedA; | ||
|
||
j = 0; | ||
while (j < NNBAR) { | ||
for l = 0 to 4 { | ||
B[(int)j + l] = E[(int)j + l]; | ||
} | ||
j += 4; | ||
} | ||
s_B = B; s_S = S; s_E = E; | ||
|
||
// calculate A and B += S * A | ||
b[u16 0] = 0; | ||
|
||
while (b[u16 0] < N) { | ||
A_row = __shake128_gen_A(A_row, b); | ||
|
||
for l = 0 to NBAR { | ||
k = s_k; S = s_S; | ||
|
||
k = (64u)b[u16 0]; | ||
s = S[l * N + (int)k]; | ||
|
||
s_k = k; s_S = S; | ||
|
||
j = s_j; B = s_B; | ||
j = 0; | ||
while (j < N) { | ||
tmp = A_row[(int)j]; | ||
tmp *= s; | ||
B[l * N + (int)j] += tmp; | ||
|
||
j += 1; | ||
} | ||
s_j = j; s_B = B; | ||
} | ||
|
||
b[u16 0] += 1; | ||
} | ||
|
||
return B; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
fn __SB_plus_E(reg ptr u16[NBAR * NBAR] V, reg ptr u16[NNBAR] S B, reg ptr u16[NBAR * NBAR] E) -> stack u16[NBAR * NBAR] { | ||
reg u64 k tj; | ||
reg u16 tmp ac; | ||
inline int i j l; | ||
|
||
k = 0; | ||
while (k < NBAR * NBAR) { | ||
for l = 0 to 4 { | ||
V[(int)k + l] = E[(int)k + l]; | ||
} | ||
k += 4; | ||
} | ||
|
||
for i = 0 to NBAR { | ||
for j = 0 to NBAR { | ||
k = 0; | ||
ac = 0; | ||
while (k < N) { | ||
tmp = S[i * N + (int)k]; | ||
|
||
// NOTE: why is this needed ? | ||
tj = j + NBAR * k; | ||
tmp *= B[(int)tj]; | ||
|
||
ac += tmp; | ||
k += 1; | ||
} | ||
|
||
V[i * NBAR + j] += ac; | ||
V[i * NBAR + j] &= (1 << D) - 1; | ||
} | ||
} | ||
|
||
return V; | ||
} | ||
|
||
#[returnaddress="stack"] | ||
fn __mul_BS(reg ptr u16[NBAR * NBAR] M, reg ptr u16[NNBAR]B S) -> stack u16[NBAR * NBAR] { | ||
reg u64 k tj; | ||
reg u16 tmp; | ||
inline int i j; | ||
|
||
for i = 0 to NBAR { | ||
for j = 0 to NBAR { | ||
M[i * NBAR + j] = 0; | ||
|
||
k = 0; | ||
while (k < N) { | ||
tmp = B[i * N + (int)k]; | ||
|
||
tj = j * N; | ||
// NOTE: why is this needed ? register allocation, k and tj must be merged will be raised | ||
tj += k; | ||
tmp *= S[(int)tj]; | ||
|
||
M[i * NBAR + j] += tmp; | ||
|
||
k += 1; | ||
} | ||
M[i * NBAR + j] &= (1 << D) - 1; | ||
} | ||
} | ||
|
||
return M; | ||
} |
Oops, something went wrong.