Skip to content

Commit

Permalink
Stack opt key pair
Browse files Browse the repository at this point in the history
* Minor clean up
  • Loading branch information
dop-amin committed Apr 8, 2024
1 parent e46e05b commit 54709e7
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 76 deletions.
68 changes: 47 additions & 21 deletions crypto_sign/dilithium3/m4fstack/sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
* Returns 0 (success)
**************************************************/
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
unsigned int i, j;
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES];
uint8_t tr[TRBYTES];
const uint8_t *rho, *rhoprime, *key;
polyvecl mat[K];
polyvecl s1, s1hat;
polyveck s2, t1, t0;

poly tA, tB, tC;

/* Get randomness for rho, rhoprime and key */
randombytes(seedbuf, SEEDBYTES);
Expand All @@ -38,31 +38,57 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
rhoprime = rho + SEEDBYTES;
key = rhoprime + CRHBYTES;

/* Expand matrix */
polyvec_matrix_expand(mat, rho);

/* Sample short vectors s1 and s2 */
polyvecl_uniform_eta(&s1, rhoprime, 0);
polyveck_uniform_eta(&s2, rhoprime, L);
pack_sk_rho(sk, rho);
pack_sk_key(sk, key);
pack_pk_rho(pk, rho);

/* Matrix-vector multiplication */
s1hat = s1;
polyvecl_ntt(&s1hat);
polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat);
polyveck_reduce(&t1);
polyveck_invntt_tomont(&t1);
for (i = 0; i < K; i++)
{
/* Expand part of s1 */
poly_uniform_eta(&tC, rhoprime, 0);
if (i == 0)
{
pack_sk_s1(sk, &tC, 0);
}
poly_ntt(&tC);
/* expand part of the matrix */
poly_uniform(&tB, rho, (i << 8) + 0);
/* partial matrix-vector multiplication */
poly_pointwise_montgomery(&tA, &tB, &tC);
for(j = 1; j < L; j++)
{
/* Expand part of s1 */
poly_uniform_eta(&tC, rhoprime, j);
if (i == 0)
{
pack_sk_s1(sk, &tC, j);
}
poly_ntt(&tC);
poly_uniform(&tB, rho, (i << 8) + j);
poly_pointwise_acc_montgomery(&tA, &tB, &tC);
}

poly_reduce(&tA);
poly_invntt_tomont(&tA);

/* Add error vector s2 */
polyveck_add(&t1, &t1, &s2);
/* Add error vector s2 */
/* Sample short vector s2 */
poly_uniform_eta(&tB, rhoprime, L + i);
pack_sk_s2(sk, &tB, i);
poly_add(&tA, &tA, &tB);

/* Extract t1 and write public key */
polyveck_caddq(&t1);
polyveck_power2round(&t1, &t0, &t1);
pack_pk(pk, rho, &t1);
/* Compute t{0,1} */
poly_caddq(&tA);
poly_power2round(&tC, &tB, &tA);
pack_sk_t0(sk, &tB, i);
pack_pk_t1(pk, &tC, i);

}

/* Compute H(rho, t1) and write secret key */
shake256(tr, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
pack_sk(sk, rho, tr, key, &t0, &s1, &s2);
pack_sk_tr(sk, tr);

return 0;
}
Expand Down
179 changes: 127 additions & 52 deletions crypto_sign/dilithium3/m4fstack/stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ void unpack_sk_s2(smallpoly *a, const uint8_t *sk, size_t idx) {

// TODO: in the end increase this buffer size as far as possible
#define POLY_UNIFORM_BUFFERSIZE 3
void poly_uniform_pointwise_montgomery_polywadd_stack(uint8_t wcomp[3*N], poly *b, uint8_t seed[SEEDBYTES], uint16_t nonce, shake128incctx *state){
void poly_uniform_pointwise_montgomery_polywadd_stack(uint8_t wcomp[3*N], poly *b, const uint8_t seed[SEEDBYTES], uint16_t nonce, shake128incctx *state){
int32_t t;
uint8_t buf[POLY_UNIFORM_BUFFERSIZE*3];
{
Expand Down Expand Up @@ -438,7 +438,6 @@ size_t poly_make_hint_stack(poly *a, poly *t, uint8_t w[768]){
return hints_n;
}

// TODO: remove this later
void unpack_sk_stack(uint8_t rho[SEEDBYTES],
uint8_t tr[TRBYTES],
uint8_t key[SEEDBYTES],
Expand All @@ -459,56 +458,6 @@ void unpack_sk_stack(uint8_t rho[SEEDBYTES],
sk += TRBYTES;
}

/* TODO: remove this function */
/*************************************************
* Name: unpack_sig_h
*
* Description: Unpack only h from signature sig = (c, z, h).
*
* Arguments: - polyveck *h: pointer to output hint vector h
* - const unsigned char sig[]: byte array containing
* bit-packed signature
*
* Returns 1 in case of malformed signature; otherwise 0.
**************************************************/
int unpack_sig_h(poly *h, unsigned int idx, const unsigned char sig[CRYPTO_BYTES]) {
sig += L * POLYZ_PACKEDBYTES;
sig += CTILDEBYTES;
/* Decode h */
unsigned int k = 0;

if (idx > 0)
{
k = sig[OMEGA + (idx - 1)];
}

for (unsigned int j = 0; j < N; ++j) {
h->coeffs[j] = 0;
}

if (sig[OMEGA + idx] < k || sig[OMEGA + idx] > OMEGA) {
return 1;
}

for (unsigned int j = k; j < sig[OMEGA + idx]; ++j) {
/* Coefficients are ordered for strong unforgeability */
if (j > k && sig[j] <= sig[j - 1]) {
return 1;
}
h->coeffs[sig[j]] = 1;
}

/* TODO: extract this check, redundant here */
k = sig[OMEGA + (K - 1)];
/* Extra indices are zero for strong unforgeability */
for (unsigned int j = k; j < OMEGA; ++j) {
if (sig[j]) {
return 1;
}
}
return 0;
}

/*************************************************
* Name: unpack_sig_h_indices
*
Expand Down Expand Up @@ -591,4 +540,130 @@ void poly_use_hint_stack(poly *b, const poly *a, uint8_t h_i[OMEGA], unsigned in
}

}
}

/*************************************************
* Name: pack_pk_rho
*
* Description: Bit-pack only rho in public key pk = (rho, t1).
*
* Arguments: - unsigned char pk[]: output byte array
* - const unsigned char rho[]: byte array containing rho
**************************************************/
void pack_pk_rho(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
const unsigned char rho[SEEDBYTES]) {
for (unsigned int i = 0; i < SEEDBYTES; ++i) {
pk[i] = rho[i];
}
}

/*************************************************
* Name: pack_pk_t1
*
* Description: Bit-pack only the t1 elem at idx in public key pk = (rho, t1).
*
* Arguments: - unsigned char pk[]: output byte array
* - const polyveck *t1: pointer to vector t1
* - const unsigned int idx: index to the elem to pack
**************************************************/
void pack_pk_t1(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
const poly *t1,
const unsigned int idx) {
pk += SEEDBYTES;
polyt1_pack(pk + idx * POLYT1_PACKEDBYTES, t1);
}

/*************************************************
* Name: pack_sk_s1
*
* Description: Bit-pack only some element of s1 in secret key sk = (rho, key, tr, s1, s2, t0).
*
* Arguments: - unsigned char sk[]: output byte array
* - const poly *s1_elem: pointer to vector element idx in s1
* - const unisgned int idx: index to the element of s1 that should be packed
**************************************************/
void pack_sk_s1(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const poly *s1_elem,
const unsigned int idx) {
sk += 2 * SEEDBYTES + TRBYTES;
polyeta_pack(sk + idx * POLYETA_PACKEDBYTES, s1_elem);
}

/*************************************************
* Name: pack_sk_s2
*
* Description: Bit-pack only some element of s2 in secret key sk = (rho, key, tr, s1, s2, t0).
*
* Arguments: - unsigned char sk[]: output byte array
* - const poly *s2_elem: pointer to vector element idx in s2
* - const unsigned int idx: index to the element of s1 that should be packed
**************************************************/
void pack_sk_s2(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const poly *s2_elem,
const unsigned int idx) {
sk += 2 * SEEDBYTES + TRBYTES + L * POLYETA_PACKEDBYTES;
polyeta_pack(sk + idx * POLYETA_PACKEDBYTES, s2_elem);
}

/*************************************************
* Name: pack_sk_t0
*
* Description: Bit-pack only some element of t0 in secret key sk = (rho, key, tr, s1, s2, t0).
*
* Arguments: - unsigned char sk[]: output byte array
* - const poly *t0_elem: pointer to vector element idx in s2
* - const unsigned int idx: index to the element of s1 that should be packed
**************************************************/
void pack_sk_t0(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const poly *t0_elem,
const unsigned int idx) {
sk += 2 * SEEDBYTES + TRBYTES + L * POLYETA_PACKEDBYTES + K * POLYETA_PACKEDBYTES;
polyt0_pack(sk + idx * POLYT0_PACKEDBYTES, t0_elem);
}

/*************************************************
* Name: pack_sk_rho
*
* Description: Bit-pack only rho in secret key sk = (rho, key, tr, s1, s2, t0).
*
* Arguments: - unsigned char sk[]: output byte array
* - const unsigned char rho[]: byte array containing rho
**************************************************/
void pack_sk_rho(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char rho[SEEDBYTES]) {
for (unsigned int i = 0; i < SEEDBYTES; ++i) {
sk[i] = rho[i];
}
}

/*************************************************
* Name: pack_sk_key
*
* Description: Bit-pack only key in secret key sk = (rho, key, tr, s1, s2, t0).
*
* Arguments: - unsigned char sk[]: output byte array
* - const unsigned char key[]: byte array containing key
**************************************************/
void pack_sk_key(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char key[SEEDBYTES]) {
sk += SEEDBYTES;
for (unsigned int i = 0; i < SEEDBYTES; ++i) {
sk[i] = key[i];
}
}

/*************************************************
* Name: pack_sk_tr
*
* Description: Bit-pack only tr in secret key sk = (rho, key, tr, s1, s2, t0).
*
* Arguments: - unsigned char sk[]: output byte array
* - const unsigned char tr[]: byte array containing tr
**************************************************/
void pack_sk_tr(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char tr[TRBYTES]) {
sk += 2*SEEDBYTES;
for (unsigned int i = 0; i < TRBYTES; ++i) {
sk[i] = tr[i];
}
}
32 changes: 29 additions & 3 deletions crypto_sign/dilithium3/m4fstack/stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,45 @@ void poly_lowbits(poly *a0, const poly *a);

void unpack_sk_s1(smallpoly *a, const uint8_t *sk, size_t idx);
void unpack_sk_s2(smallpoly *a, const uint8_t *sk, size_t idx);
int unpack_sig_h(poly *h, unsigned int idx, const unsigned char sig[CRYPTO_BYTES]);

void poly_uniform_pointwise_montgomery_polywadd_stack(uint8_t wcomp[3*N], poly *b, uint8_t seed[SEEDBYTES], uint16_t nonce, shake128incctx *state);
void poly_uniform_pointwise_montgomery_polywadd_stack(uint8_t wcomp[3*N], poly *b, const uint8_t seed[SEEDBYTES], uint16_t nonce, shake128incctx *state);
void poly_uniform_gamma1_stack(poly *a, const uint8_t seed[CRHBYTES], uint16_t nonce, shake256incctx *state);
void poly_uniform_gamma1_add_stack(poly *a, poly *b, const uint8_t seed[CRHBYTES], uint16_t nonce, shake256incctx *state);

size_t poly_make_hint_stack(poly *a, poly *t, uint8_t w[768]);
int unpack_sig_h_indices(uint8_t h_i[OMEGA], unsigned int * number_of_hints, unsigned int idx, const unsigned char sig[CRYPTO_BYTES]);
void poly_use_hint_stack(poly *b, const poly *a, uint8_t h_i[OMEGA], unsigned int number_of_hints);

// TODO: replace this with individual functions later
void unpack_sk_stack(uint8_t rho[SEEDBYTES],
uint8_t tr[TRBYTES],
uint8_t key[SEEDBYTES],
const uint8_t sk[CRYPTO_SECRETKEYBYTES]);

void pack_pk_rho(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
const unsigned char rho[SEEDBYTES]);

void pack_pk_t1(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
const poly *t1,
const unsigned int idx);

void pack_sk_s1(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const poly *s1_elem,
const unsigned int idx);

void pack_sk_s2(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const poly *s2_elem,
const unsigned int idx);

void pack_sk_t0(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const poly *t0_elem,
const unsigned int idx);

void pack_sk_rho(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char rho[SEEDBYTES]);

void pack_sk_key(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char key[SEEDBYTES]);

void pack_sk_tr(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char tr[TRBYTES]);
#endif

0 comments on commit 54709e7

Please sign in to comment.