From 5ff8d9092a3ce1b50cd6f3fcd61a1ae8a03ea3b3 Mon Sep 17 00:00:00 2001 From: "Thing-han, Lim" <15379156+potsrevennil@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:50:29 +0800 Subject: [PATCH] update frodo976shake accordingly --- .../frodo/common/amd64/ref/shake128_opt.jinc | 54 +--- .../frodo/common/amd64/ref/shake256_opt.jinc | 17 +- .../frodo/frodo640shake/amd64/ref/kem.jinc | 4 +- .../frodo/frodo976shake/amd64/ref/indcpa.jinc | 126 ++++++++ .../frodo/frodo976shake/amd64/ref/kem.jazz | 15 +- .../frodo/frodo976shake/amd64/ref/kem.jinc | 285 +++++++----------- 6 files changed, 256 insertions(+), 245 deletions(-) create mode 100644 src/crypto_kem/frodo/frodo976shake/amd64/ref/indcpa.jinc diff --git a/src/crypto_kem/frodo/common/amd64/ref/shake128_opt.jinc b/src/crypto_kem/frodo/common/amd64/ref/shake128_opt.jinc index a7d481f7..657042f3 100644 --- a/src/crypto_kem/frodo/common/amd64/ref/shake128_opt.jinc +++ b/src/crypto_kem/frodo/common/amd64/ref/shake128_opt.jinc @@ -268,7 +268,7 @@ fn __shake128_pkh_opt( return out; } -fn __shake128_SE_k_opt2( +fn __shake128_SE_k_opt( #spill_to_mmx reg ptr u8[BYTES_SEED_SE + BYTES_SEC] out, #spill_to_mmx reg const ptr u8[2 * BYTES_SEC + BYTES_SALT] in) -> reg ptr u8[BYTES_SEED_SE + BYTES_SEC] { @@ -319,58 +319,6 @@ fn __shake128_SE_k_opt2( } -fn __shake128_SE_k_opt( - #spill_to_mmx reg ptr u8[1 + BYTES_SEED_SE + BYTES_SEC] out, - #spill_to_mmx reg const ptr u8[2 * BYTES_SEC + BYTES_SALT] in) --> reg ptr u8[1 + BYTES_SEED_SE + BYTES_SEC] { - #spill_to_mmx reg u64 i; - - stack u64[25] s_state; - reg ptr u64[25] state; - reg u64 offset t0 zero; - inline int INLEN OUTLEN; - - INLEN = 2 * BYTES_SEC + BYTES_SALT; - OUTLEN = BYTES_SEED_SE + BYTES_SEC; - - state = s_state; - - i = 0; - while (i < INLEN/8) { - t0 = in[u64 i]; - state[i] = t0; - - i += 1; - } - ?{}, zero = #set0(); - - i = INLEN/8; - while (i < 25) { - state[i] = zero; - i += 1; - } - - state[u8 INLEN] = 0x1f; - state[u8 SHAKE128_RATE-1] = 0x80; - - () = #spill(out); - - state = __keccakf1600_ref1(state); - - () = #unspill(out); - - i = 0; - while (i < OUTLEN/8) { - t0 = state[u64 i]; - offset = #LEA(1+8*i); - out.[u64 offset] = t0; - - i += 1; - } - - return out; -} - fn __shake128_encap_r_opt( #spill_to_mmx reg ptr u8[2 * (2 * NNBAR + NBAR * NBAR)] out, #spill_to_mmx reg const ptr u8[1 + BYTES_SEED_SE] in) diff --git a/src/crypto_kem/frodo/common/amd64/ref/shake256_opt.jinc b/src/crypto_kem/frodo/common/amd64/ref/shake256_opt.jinc index f89b82eb..a3514809 100644 --- a/src/crypto_kem/frodo/common/amd64/ref/shake256_opt.jinc +++ b/src/crypto_kem/frodo/common/amd64/ref/shake256_opt.jinc @@ -89,11 +89,11 @@ fn __shake256_r_opt( i = 0; while (i < OUTRND * SHAKE256_RATE/8) { - () = #spill(i, out); + () = #spill(i, j, out); state = __keccakf1600_ref1(state); - () = #unspill(i, out); + () = #unspill(i, j, out); j = 0; while (j < SHAKE256_RATE/8) { @@ -107,11 +107,11 @@ fn __shake256_r_opt( i += SHAKE256_RATE/8; } - () = #spill(i, out); + () = #spill(i, j, out); state = __keccakf1600_ref1(state); - () = #unspill(i, out); + () = #unspill(i, j, out); i = 0; while (i < (OUTLEN % SHAKE256_RATE) / 8) { @@ -196,14 +196,14 @@ fn __shake256_pkh_opt( } fn __shake256_SE_k_opt( - #spill_to_mmx reg ptr u8[1 + BYTES_SEED_SE + BYTES_SEC] out, + #spill_to_mmx reg ptr u8[BYTES_SEED_SE + BYTES_SEC] out, #spill_to_mmx reg const ptr u8[2 * BYTES_SEC + BYTES_SALT] in) --> reg ptr u8[1 + BYTES_SEED_SE + BYTES_SEC] { +-> reg ptr u8[BYTES_SEED_SE + BYTES_SEC] { #spill_to_mmx reg u64 i; stack u64[25] s_state; reg ptr u64[25] state; - reg u64 offset t0 zero; + reg u64 t0 zero; inline int INLEN OUTLEN; INLEN = 2 * BYTES_SEC + BYTES_SALT; @@ -238,8 +238,7 @@ fn __shake256_SE_k_opt( i = 0; while (i < OUTLEN/8) { t0 = state[u64 i]; - offset = #LEA(1+8*i); - out.[u64 offset] = t0; + out[u64 i] = t0; i += 1; } diff --git a/src/crypto_kem/frodo/frodo640shake/amd64/ref/kem.jinc b/src/crypto_kem/frodo/frodo640shake/amd64/ref/kem.jinc index 8c5f5562..77dd9e06 100644 --- a/src/crypto_kem/frodo/frodo640shake/amd64/ref/kem.jinc +++ b/src/crypto_kem/frodo/frodo640shake/amd64/ref/kem.jinc @@ -121,7 +121,7 @@ fn __frodo_amd64_ref_enc_derand( pkh_u_salt[0:BYTES_SEC] = __shake128_pkh_opt(pkh_u_salt[0:BYTES_SEC], pk); // seedSE || k - seedSE_k = __shake128_SE_k_opt2(seedSE_k, pkh_u_salt); + seedSE_k = __shake128_SE_k_opt(seedSE_k, pkh_u_salt); () = #unspill(coins); ct_k[0:BYTES_CT - BYTES_SALT] = __indcpa_enc_derand(ct_k[0:BYTES_CT - BYTES_SALT], coins[0:BYTES_SEC], pk, seedSE_k[0:BYTES_SEED_SE]); @@ -217,7 +217,7 @@ fn _frodo_amd64_ref_dec(reg u64 ssp ctp skp) { pkh_u_salt[BYTES_SEC:BYTES_SEC] = __indcpa_dec(pkh_u_salt[BYTES_SEC:BYTES_SEC], ct_k[0:BYTES_CT - BYTES_SALT], ST); () = #spill(ssp); - seedSE_k = __shake128_SE_k_opt2(seedSE_k, pkh_u_salt); + seedSE_k = __shake128_SE_k_opt(seedSE_k, pkh_u_salt); ct2 = __indcpa_enc_derand(ct2, pkh_u_salt[BYTES_SEC:BYTES_SEC], pk, seedSE_k[0:BYTES_SEED_SE]); s1 = __ct_verify(ct_k[0:BYTES_CT - BYTES_SALT], ct2); diff --git a/src/crypto_kem/frodo/frodo976shake/amd64/ref/indcpa.jinc b/src/crypto_kem/frodo/frodo976shake/amd64/ref/indcpa.jinc new file mode 100644 index 00000000..534481e9 --- /dev/null +++ b/src/crypto_kem/frodo/frodo976shake/amd64/ref/indcpa.jinc @@ -0,0 +1,126 @@ +inline +fn __indcpa_keypair_derand( + #spill_to_mmx reg ptr u8[BYTES_SEED_A + BYTES_SEED_SE] coins +) -> stack u8[BYTES_PK], stack u8[2*NNBAR] { + stack u8[BYTES_PK] pk; // seedA || b + stack u8[2*NNBAR] sk; // S_T + stack u16[2 * NNBAR] SE; + stack u16[NNBAR] B; + + reg u64 i t; + + i = 0; + while (i < BYTES_SEED_A/8) { + t = coins[u64 i]; + pk[u64 i] = t; + i += 1; + } + + () = #spill(coins); + // gen S || E + SE = __shake256_r_opt(SE, coins[BYTES_SEED_A:BYTES_SEED_SE]); + + SE = __sample_2NNBAR(SE); + + // B = A*S+E + B = __AS_plus_E_opt(B, pk[0:BYTES_SEED_A], SE[0:NNBAR], SE[NNBAR:NNBAR]); + + // pack + pk[BYTES_SEED_A:D * N] = __pack_B(pk[BYTES_SEED_A:D * N], B); + + i = 0; + while (i < 2 * NNBAR / 8) { + t = SE[u64 i]; + sk[u64 i] = t; + i += 1; + } + + return pk, sk; +} + +inline +fn __indcpa_enc_derand( + #spill_to_mmx reg ptr u8[BYTES_CT - BYTES_SALT] ct, + #spill_to_mmx reg ptr u8[BYTES_SEC] u, + #spill_to_mmx reg ptr u8[BYTES_PK] pk, + #spill_to_mmx reg ptr u8[BYTES_SEED_SE] coins +) -> reg ptr u8[BYTES_CT - BYTES_SALT] { + reg u64 i t; + + // 0x96 || seed_SE + stack u8[1 + BYTES_SEED_SE] seedSE; + seedSE[0] = 0x96; + + // S' || E' || E'' + stack u16[2 * NNBAR + NBAR * NBAR] SEE; + stack u16[NNBAR] B; + reg ptr u16[NNBAR] Bp; + stack u16[NBAR * NBAR] C; + reg ptr u16[NBAR * NBAR] V; + + // stack u8[BYTES_CT - BYTES_SALT] ct; + + i = 0; + while (i < BYTES_SEED_SE/8) { + t = coins[u64 i]; + seedSE.[u64 1 + 8*i] = t; + i += 1; + } + + // B <- Unpack(b) + B = __unpack_B(B, pk[BYTES_SEED_A:D * N]); + C = __encode(C, u); + + () = #spill(ct, u, pk, coins); + + // gen input bit string for sampling S and E + SEE = __shake256_encap_r_opt(SEE, seedSE); + + // S' || E' + SEE[0:2 * NNBAR] = __sample_2NNBAR(SEE[0:2 * NNBAR]); + // E'' + SEE[NNBAR * 2:NBAR * NBAR] = __sample_NBAR2(SEE[NNBAR * 2:NBAR * NBAR]); + + // B' = S'A + E'' + Bp = SEE[NNBAR:NNBAR]; + + () = #unspill(pk); + Bp = __SA_plus_E_opt(Bp, pk[0:BYTES_SEED_A], SEE[0:NNBAR]); + + // V = S'B + E'' + V = SEE[NNBAR*2:NBAR*NBAR]; + V = __SB_plus_E_opt(V, SEE[0:NNBAR], B); + + // C = V + Encode(u) + C = __matrix_add(C, V); + + // c1 <- Pack(B') + () = #unspill(ct); + ct[0:D * N] = __pack_B(ct[0:D * N], Bp); + // c2 <- Pack(C) + ct[D * N: D * NBAR] = __pack_C(ct[D * N: D * NBAR], C); + + return ct; +} + +inline +fn __indcpa_dec( + #spill_to_mmx reg ptr u8[BYTES_SEC] pt, + #spill_to_mmx reg ptr u8[BYTES_CT - BYTES_SALT] ct, + #spill_to_mmx reg ptr u8[2*NNBAR] sk +) -> reg ptr u8[BYTES_SEC] { + stack u16[NNBAR] Bp; + stack u16[NBAR * NBAR] M C; + + // B' <- Unpack(c1) + Bp = __unpack_B(Bp, ct[0:D * N]); + // C <- Unpack(c2) + C = __unpack_C(C, ct[D * N:D * NBAR]); + + // M = C - B'S + M = __mul_BS_opt(M, Bp, sk); + M = __matrix_sub(M, C); + pt = __decode(pt, M); + + return pt; +} diff --git a/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jazz b/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jazz index c64c8260..3edd6dd1 100644 --- a/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jazz +++ b/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jazz @@ -1,36 +1,41 @@ from Jade require "crypto_kem/frodo/common/frodo976_params.jinc" from Jade require "crypto_kem/frodo/frodo976shake/amd64/ref/kem.jinc" -export fn jade_kem_frodo_frodo976shake_amd64_ref_keypair_derand(#public reg u64 pkp skp coinsp) -> #public reg u64 { +export fn jade_kem_frodo_frodo976shake_amd64_ref_keypair_derand(reg u64 pkp skp coinsp) -> reg u64 { reg u64 r; + _ = #init_msf(); _frodo_amd64_ref_keypair_derand(pkp, skp, coinsp); ?{}, r = #set0(); return r; } -export fn jade_kem_frodo_frodo976shake_amd64_ref_keypair(#public reg u64 pkp skp) -> #public reg u64 { +export fn jade_kem_frodo_frodo976shake_amd64_ref_keypair(reg u64 pkp skp) -> reg u64 { reg u64 r; + _ = #init_msf(); _frodo_amd64_ref_keypair(pkp, skp); ?{}, r = #set0(); return r; } -export fn jade_kem_frodo_frodo976shake_amd64_ref_enc_derand(#public reg u64 ctp ssp pkp coinsp) -> #public reg u64 { +export fn jade_kem_frodo_frodo976shake_amd64_ref_enc_derand(reg u64 ctp ssp pkp coinsp) -> reg u64 { reg u64 r; + _ = #init_msf(); _frodo_amd64_ref_enc_derand(ctp, ssp, pkp, coinsp); ?{}, r = #set0(); return r; } -export fn jade_kem_frodo_frodo976shake_amd64_ref_enc(#public reg u64 ctp ssp pkp) -> #public reg u64 { +export fn jade_kem_frodo_frodo976shake_amd64_ref_enc(reg u64 ctp ssp pkp) -> reg u64 { reg u64 r; + _ = #init_msf(); _frodo_amd64_ref_enc(ctp, ssp, pkp); ?{}, r = #set0(); return r; } -export fn jade_kem_frodo_frodo976shake_amd64_ref_dec(#public reg u64 ssp ctp skp) -> #public reg u64 { +export fn jade_kem_frodo_frodo976shake_amd64_ref_dec(reg u64 ssp ctp skp) -> reg u64 { reg u64 r; + _ = #init_msf(); _frodo_amd64_ref_dec(ssp, ctp, skp); ?{}, r = #set0(); return r; diff --git a/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jinc b/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jinc index c1ed48cd..aa677759 100644 --- a/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jinc +++ b/src/crypto_kem/frodo/frodo976shake/amd64/ref/kem.jinc @@ -5,81 +5,80 @@ from Jade require "crypto_kem/frodo/common/amd64/ref/noise.jinc" from Jade require "crypto_kem/frodo/common/amd64/ref/matrix.jinc" from Jade require "crypto_kem/frodo/common/amd64/ref/matrix_mul_opt.jinc" from Jade require "crypto_kem/frodo/common/amd64/ref/pack.jinc" +require "./indcpa.jinc" // coins = s || seed SE || z +inline fn __frodo_amd64_ref_keypair_derand( reg u64 pkp skp, - #spill_to_mmx reg ptr u8[BYTES_SEED_A + BYTES_SEED_SE + BYTES_SEC] coins) { - stack u16[2 * NNBAR] SE; - stack u16[NNBAR] B; - - inline int k; - reg u64 i j; + #spill_to_mmx reg ptr u8[BYTES_SEC + BYTES_SEED_SE + BYTES_SEED_A] coins) { + reg u64 i t; // seedA || b stack u8[BYTES_PK] pk; + stack u8[BYTES_SEED_A + BYTES_SEED_SE] indcoins; + stack u8[BYTES_SEC] pkh; - // s || seedA || b || S_T || pkh - stack u8[BYTES_SK] sk; - - () = #spill(i, j, pkp, skp); + // S_T + stack u8[2*NNBAR] sk; - for k = 0 to BYTES_SEC/8 { - sk[u64 k] = coins[u64 k]; + i = 0; + while (i < BYTES_SEC/8) { + t = coins[u64 i]; + [skp + i*8] = t; + i += 1; } - // gen seedA - pk[0:BYTES_SEED_A] = __shake256_seed_A_opt(pk[0:BYTES_SEED_A], coins[BYTES_SEC + BYTES_SEED_SE:BYTES_SEED_A]); - - // gen S || E - SE = __shake256_r_opt(SE, coins[BYTES_SEC:BYTES_SEED_SE]); - SE = __sample_2NNBAR(SE); + // copy seedSE + i = 0; + while (i < BYTES_SEED_SE/8) { + t = coins[u64 BYTES_SEC/8 + i]; + indcoins[u64 BYTES_SEED_A/8 + i] = t; + i += 1; + } - () = #spill(coins); + () = #spill(pkp, skp, coins); + indcoins[0:BYTES_SEED_A] = __shake256_seed_A_opt(indcoins[0:BYTES_SEED_A], coins[BYTES_SEC + BYTES_SEED_SE:BYTES_SEED_A]); - // B = A*S+E - B = __AS_plus_E_opt(B, pk[0:BYTES_SEED_A], SE[0:NNBAR], SE[NNBAR:NNBAR]); + pk, sk = __indcpa_keypair_derand(indcoins); + pkh = __shake256_pkh_opt(pkh, pk); - // pack - pk[BYTES_SEED_A:D * N] = __pack_B(pk[BYTES_SEED_A:D * N], B); + () = #unspill(pkp, skp); - () = #unspill(i); i = 0; while (i < BYTES_PK/8) { - sk[u64 BYTES_SEC/8 + i] = pk[u64 i]; + t = pk[u64 i]; + [skp + BYTES_SEC + i*8] = t; i += 1; } i = 0; while (i < 2 * NNBAR / 8) { - sk[u64 BYTES_SEC/8 + BYTES_PK/8 + i] = SE[u64 i]; + t = sk[u64 i]; + [skp + BYTES_SEC + BYTES_PK + i*8] = t; i += 1; } - () = #spill(i); - - sk[BYTES_SEC + BYTES_PK + 2 * NNBAR : BYTES_SEC] = __shake256_pkh_opt(sk[BYTES_SEC + BYTES_PK + 2 * NNBAR:BYTES_SEC], pk); - () = #unspill(i, j, pkp, skp); - i = 0; j = 0; + i = 0; while (i < BYTES_PK/8) { - [pkp + j] = pk[u64 i]; + t = pk[u64 i]; + [pkp + i*8] = t; i += 1; - j += 8; } - i = 0; j = 0; - while (i < BYTES_SK/8) { - [skp + j] = sk[u64 i]; + i = 0; + while (i < BYTES_SEC/8) { + t = pkh[u64 i]; + [skp + BYTES_SK - BYTES_SEC + i*8] = t; i += 1; - j += 8; } } -#[returnaddress="stack"] +inline fn __frodo_amd64_ref_enc_derand( reg u64 ctp ssp pkp, #spill_to_mmx reg ptr u8[BYTES_SEC + BYTES_SALT] coins) { - reg u64 i j; + reg u64 i t; inline int k; // seedA || b @@ -90,40 +89,34 @@ fn __frodo_amd64_ref_enc_derand( // pkh || u || salt stack u8[BYTES_SEC * 2 + BYTES_SALT] pkh_u_salt; - // 0x96 || seedSE || k - stack u8[1 + BYTES_SEED_SE + BYTES_SEC] seedSE_k; - seedSE_k[0] = 0x96; - - // S' || E' || E'' - stack u16[2 * NNBAR + NBAR * NBAR] SEE; + // seedSE || k + stack u8[BYTES_SEED_SE + BYTES_SEC] seedSE_k; - stack u16[NNBAR] B; - reg ptr u16[NNBAR] Bp; - stack u16[NBAR * NBAR] C; - reg ptr u16[NBAR * NBAR] V; stack u8[BYTES_SEC] ss; - pkp = pkp; - () = #spill(ctp, ssp, i, j); - // gen u || salt - for k = 0 to (BYTES_SEC + BYTES_SALT)/8 { - pkh_u_salt[u64 BYTES_SEC/8 + k] = coins[u64 k]; + i = 0; + while (i < (BYTES_SEC + BYTES_SALT)/8) { + t = coins[u64 i]; + pkh_u_salt[u64 BYTES_SEC/8 + i] = t; + i += 1; } - for k = 0 to BYTES_SALT/8 { - ct_k[u64 (D * N + D * NBAR)/8 + k] = pkh_u_salt[u64 (BYTES_SEC * 2)/8 + k]; + i = 0; + while (i < BYTES_SALT/8) { + t = coins[u64 BYTES_SEC/8 + i]; + ct_k[u64 (BYTES_CT - BYTES_SALT)/8 + i] = t; + i += 1; } - () = #unspill(i, j); // read pk - i = 0; j = 0; + i = 0; while (i < BYTES_PK/8) { - #declassify pk[u64 i] = [pkp + j]; + #declassify pk[u64 i] = [pkp + i*8]; i += 1; - j += 8; } - () = #spill(i, j); + + () = #spill(ctp, ssp, coins); // pkh pkh_u_salt[0:BYTES_SEC] = __shake256_pkh_opt(pkh_u_salt[0:BYTES_SEC], pk); @@ -131,175 +124,116 @@ fn __frodo_amd64_ref_enc_derand( // seedSE || k seedSE_k = __shake256_SE_k_opt(seedSE_k, pkh_u_salt); + () = #unspill(coins); + ct_k[0:BYTES_CT - BYTES_SALT] = __indcpa_enc_derand(ct_k[0:BYTES_CT - BYTES_SALT], coins[0:BYTES_SEC], pk, seedSE_k[0:BYTES_SEED_SE]); + // copy k - for k = 0 to BYTES_SEC/8 { - ct_k[u64 BYTES_CT/8 + k] = seedSE_k.[u64 1 + BYTES_SEED_SE + 8*k]; + i = 0; + while (i < BYTES_SEC/8) { + t = seedSE_k[u64 BYTES_SEED_SE/8 + i]; + ct_k[u64 BYTES_CT/8 + i] = t; + i += 1; } - // gen input bit string for sampling S and E - SEE = __shake256_encap_r_opt(SEE, seedSE_k[0 : 1 + BYTES_SEED_SE]); - - // S' || E' - SEE[0:2 * NNBAR] = __sample_2NNBAR(SEE[0:2 * NNBAR]); - // E'' - SEE[NNBAR * 2:NBAR * NBAR] = __sample_NBAR2(SEE[NNBAR * 2:NBAR * NBAR]); - - // B' = S'A + E'' - Bp = SEE[NNBAR:NNBAR]; - Bp = __SA_plus_E_opt(Bp, pk[0:BYTES_SEED_A], SEE[0:NNBAR]); - - // c1 <- Pack(B') - ct_k[0:D * N] = __pack_B(ct_k[0:D * N], Bp); - - // B <- Unpack(b) - B = __unpack_B(B, pk[BYTES_SEED_A:D * N]); - - // V = S'B + E'' - V = SEE[NNBAR*2:NBAR*NBAR]; - V = __SB_plus_E_opt(V, SEE[0:NNBAR], B); - - // C = V + Encode(u) - C = __encode(C, pkh_u_salt[BYTES_SEC:BYTES_SEC]); - C = __matrix_add(C, V); - - // c2 <- Pack(C) - ct_k[D * N: D * NBAR] = __pack_C(ct_k[D * N: D * NBAR], C); - // ss <- shake(c1 || c2 || salt || k) ss = __shake256_ss_opt(ss, ct_k); - () = #unspill(i, j, ctp, ssp); - i = 0; j = 0; + () = #unspill(ctp, ssp); + i = 0; + _ = #init_msf(); while (i < BYTES_CT/8) { - [ctp + j] = ct_k[u64 i]; + t = ct_k[u64 i]; + [ctp + i*8] = t; i += 1; - j += 8; } for k = 0 to BYTES_SEC/8 { - [ssp + 8*k] = ss[u64 k]; + t = ss[u64 k]; + [ssp + 8*k] = t; } } -#[returnaddress="stack"] fn _frodo_amd64_ref_dec(reg u64 ssp ctp skp) { #public stack u8[BYTES_PK] pk; stack u8[2 * NNBAR] ST; stack u8[BYTES_SEC] s; stack u8[BYTES_CT + BYTES_SEC] ct_k; - stack u16[NNBAR] B Bp; - reg ptr u16[NNBAR] Bpp; - stack u16[NBAR * NBAR] M C Cp; - reg ptr u16[NBAR * NBAR] V; + stack u8[BYTES_CT - BYTES_SALT] ct2; stack u8[BYTES_SEC * 2 + BYTES_SALT] pkh_u_salt; - stack u8[1 + BYTES_SEED_SE + BYTES_SEC] seedSE_k; + stack u8[BYTES_SEED_SE + BYTES_SEC] seedSE_k; stack u8[BYTES_SEC] ss; - // S' || E' || E'' - stack u16[2 * NNBAR + NBAR * NBAR] SEE; - - reg u8 s1 s2; - reg u64 i j t; - stack u64 s_ssp s_skp; - inline int k; + reg u8 s1; + reg u64 i t; ctp = ctp; skp = skp; - s_ssp = ssp; + ssp = ssp; // copy pkh - for k = 0 to BYTES_SEC/8 { - pkh_u_salt[u64 k] = [skp + BYTES_SK - BYTES_SEC + 8*k]; + i = 0; + while (i < BYTES_SEC/8) { + t = [skp + BYTES_SK - BYTES_SEC + i*8]; + pkh_u_salt[u64 i] = t; + i += 1; } - s_skp = skp; // read ct - i = 0; j = 0; + i = 0; while (i < BYTES_CT/8) { - t = [ctp + j]; + t = [ctp + i*8]; ct_k[u64 i] = t; i += 1; - j += 8; } - for k = 0 to BYTES_SEC/8 { - s[u64 k] = [skp + 8*k]; + i = 0; + while (i < BYTES_SEC/8) { + t = [skp + i*8]; + s[u64 i] = t; + i += 1; } - i = 0; j = 0; + i = 0; while (i < BYTES_PK/8) { - #declassify pk[u64 i] = [skp + BYTES_SEC + j]; + t = [skp + BYTES_SEC + i*8]; + #declassify pk[u64 i] = t; i += 1; - j += 8; } - i = 0; j = 0; + i = 0; while (i < 2 * NNBAR/8) { - ST[u64 i] = [skp + BYTES_SEC + BYTES_PK + j]; + t = [skp + BYTES_SEC + BYTES_PK + i*8]; + ST[u64 i] = t; i += 1; - j += 8; } - () = #spill(i); - // copy salt - for k = 0 to BYTES_SALT/8 { - pkh_u_salt[u64 (BYTES_SEC * 2)/8 + k] = ct_k[u64 (BYTES_CT - BYTES_SALT)/8 + k]; - } - - // B' <- Unpack(c1) - Bp = __unpack_B(Bp, ct_k[0:D * N]); - // C <- Unpack(c2) - C = __unpack_C(C, ct_k[D * N:D * NBAR]); - - // M = C - B'S - M = __mul_BS_opt(M, Bp, ST); - M = __matrix_sub(M, C); - - pkh_u_salt[BYTES_SEC:BYTES_SEC] = __decode(pkh_u_salt[BYTES_SEC:BYTES_SEC], M); - - seedSE_k[0] = 0x96; - seedSE_k = __shake256_SE_k_opt(seedSE_k, pkh_u_salt); - - SEE = __shake256_encap_r_opt(SEE, seedSE_k[0: 1 + BYTES_SEED_SE]); - - // S' || E' - SEE[0:2 * NNBAR] = __sample_2NNBAR(SEE[0:2 * NNBAR]); - // E'' - SEE[NNBAR * 2:NBAR * NBAR] = __sample_NBAR2(SEE[NNBAR * 2:NBAR * NBAR]); - - // B'' = S'A + E' - Bpp = SEE[NNBAR:NNBAR]; - Bpp = __SA_plus_E_opt(Bpp, pk[0:BYTES_SEED_A], SEE[0:NNBAR]); - - // B'' (mod q) - () = #unspill(i); i = 0; - while (i < NNBAR) { - Bpp[i] &= (1 << D) - 1; + while (i < BYTES_SALT/8) { + t = ct_k[u64 (BYTES_CT - BYTES_SALT)/8 + i]; + pkh_u_salt[u64 (BYTES_SEC * 2)/8 + i] = t; i += 1; } - // - B = __unpack_B(B, pk[BYTES_SEED_A:BYTES_PK - BYTES_SEED_A]); - - V = SEE[NNBAR*2:NBAR*NBAR]; - V = __SB_plus_E_opt(V, SEE[0:NNBAR], B); + pkh_u_salt[BYTES_SEC:BYTES_SEC] = __indcpa_dec(pkh_u_salt[BYTES_SEC:BYTES_SEC], ct_k[0:BYTES_CT - BYTES_SALT], ST); - Cp = __encode(Cp, pkh_u_salt[BYTES_SEC:BYTES_SEC]); - Cp = __matrix_add(Cp, V); + () = #spill(ssp); + seedSE_k = __shake256_SE_k_opt(seedSE_k, pkh_u_salt); + ct2 = __indcpa_enc_derand(ct2, pkh_u_salt[BYTES_SEC:BYTES_SEC], pk, seedSE_k[0:BYTES_SEED_SE]); - s1 = __ct_verify_NNBAR(Bp, Bpp); - s2 = __ct_verify_NBAR2(C, Cp); - s1 |= s2; + s1 = __ct_verify(ct_k[0:BYTES_CT - BYTES_SALT], ct2); - ct_k[BYTES_CT:BYTES_SEC] = __ct_select(ct_k[BYTES_CT:BYTES_SEC], seedSE_k[1+BYTES_SEED_SE:BYTES_SEC], s, s1); + ct_k[BYTES_CT:BYTES_SEC] = __ct_select(ct_k[BYTES_CT:BYTES_SEC], seedSE_k[BYTES_SEED_SE:BYTES_SEC], s, s1); ss = __shake256_ss_opt(ss, ct_k); - ssp = s_ssp; - for k = 0 to BYTES_SEC/8 { - [ssp + 8*k] = ss[u64 k]; + _ = #init_msf(); + () = #unspill(ssp); + i = 0; + while (i < BYTES_SEC/8) { + t = ss[u64 i]; + [ssp + i*8] = t; + i += 1; } } @@ -316,7 +250,7 @@ fn _frodo_amd64_ref_keypair(reg u64 pkp skp) { fn _frodo_amd64_ref_keypair_derand(reg u64 pkp skp coinsp) { #public stack u8[BYTES_SEED_A + BYTES_SEED_SE + BYTES_SEC] coins; - reg u64 i; stack u64 s_i; + reg u64 i; pkp = pkp; skp = skp; @@ -327,7 +261,6 @@ fn _frodo_amd64_ref_keypair_derand(reg u64 pkp skp coinsp) { i += 1; } - s_i = i; __frodo_amd64_ref_keypair_derand(pkp, skp, coins); }