Skip to content

Commit

Permalink
Merge pull request #101 from potsrevennil/feature/frodokem
Browse files Browse the repository at this point in the history
frodo: add frodo640shake and frodo976shake reference implementation
  • Loading branch information
tfaoliveira-sb authored Apr 19, 2024
2 parents 8baa43f + e7e9e78 commit 11de617
Show file tree
Hide file tree
Showing 22 changed files with 3,771 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/crypto_kem/frodo/common/amd64/ref/encode.jinc
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;
}
108 changes: 108 additions & 0 deletions src/crypto_kem/frodo/common/amd64/ref/matrix.jinc
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;
}
191 changes: 191 additions & 0 deletions src/crypto_kem/frodo/common/amd64/ref/matrix_mul.jinc
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;
}
Loading

0 comments on commit 11de617

Please sign in to comment.