summaryrefslogtreecommitdiff
path: root/lib/liboqs/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/packing.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/liboqs/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/packing.c')
-rw-r--r--lib/liboqs/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/packing.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/lib/liboqs/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/packing.c b/lib/liboqs/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/packing.c
new file mode 100644
index 000000000..9de5826cd
--- /dev/null
+++ b/lib/liboqs/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/packing.c
@@ -0,0 +1,237 @@
+#include "params.h"
+#include "packing.h"
+#include "polyvec.h"
+#include "poly.h"
+
+/*************************************************
+* Name: pack_pk
+*
+* Description: Bit-pack public key pk = (rho, t1).
+*
+* Arguments: - uint8_t pk[]: output byte array
+* - const uint8_t rho[]: byte array containing rho
+* - const polyveck *t1: pointer to vector t1
+**************************************************/
+void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES],
+ const uint8_t rho[SEEDBYTES],
+ const polyveck *t1)
+{
+ unsigned int i;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ pk[i] = rho[i];
+ pk += SEEDBYTES;
+
+ for(i = 0; i < K; ++i)
+ polyt1_pack(pk + i*POLYT1_PACKEDBYTES, &t1->vec[i]);
+}
+
+/*************************************************
+* Name: unpack_pk
+*
+* Description: Unpack public key pk = (rho, t1).
+*
+* Arguments: - const uint8_t rho[]: output byte array for rho
+* - const polyveck *t1: pointer to output vector t1
+* - uint8_t pk[]: byte array containing bit-packed pk
+**************************************************/
+void unpack_pk(uint8_t rho[SEEDBYTES],
+ polyveck *t1,
+ const uint8_t pk[CRYPTO_PUBLICKEYBYTES])
+{
+ unsigned int i;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ rho[i] = pk[i];
+ pk += SEEDBYTES;
+
+ for(i = 0; i < K; ++i)
+ polyt1_unpack(&t1->vec[i], pk + i*POLYT1_PACKEDBYTES);
+}
+
+/*************************************************
+* Name: pack_sk
+*
+* Description: Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
+*
+* Arguments: - uint8_t sk[]: output byte array
+* - const uint8_t rho[]: byte array containing rho
+* - const uint8_t tr[]: byte array containing tr
+* - const uint8_t key[]: byte array containing key
+* - const polyveck *t0: pointer to vector t0
+* - const polyvecl *s1: pointer to vector s1
+* - const polyveck *s2: pointer to vector s2
+**************************************************/
+void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES],
+ const uint8_t rho[SEEDBYTES],
+ const uint8_t tr[SEEDBYTES],
+ const uint8_t key[SEEDBYTES],
+ const polyveck *t0,
+ const polyvecl *s1,
+ const polyveck *s2)
+{
+ unsigned int i;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ sk[i] = rho[i];
+ sk += SEEDBYTES;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ sk[i] = key[i];
+ sk += SEEDBYTES;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ sk[i] = tr[i];
+ sk += SEEDBYTES;
+
+ for(i = 0; i < L; ++i)
+ polyeta_pack(sk + i*POLYETA_PACKEDBYTES, &s1->vec[i]);
+ sk += L*POLYETA_PACKEDBYTES;
+
+ for(i = 0; i < K; ++i)
+ polyeta_pack(sk + i*POLYETA_PACKEDBYTES, &s2->vec[i]);
+ sk += K*POLYETA_PACKEDBYTES;
+
+ for(i = 0; i < K; ++i)
+ polyt0_pack(sk + i*POLYT0_PACKEDBYTES, &t0->vec[i]);
+}
+
+/*************************************************
+* Name: unpack_sk
+*
+* Description: Unpack secret key sk = (rho, tr, key, t0, s1, s2).
+*
+* Arguments: - const uint8_t rho[]: output byte array for rho
+* - const uint8_t tr[]: output byte array for tr
+* - const uint8_t key[]: output byte array for key
+* - const polyveck *t0: pointer to output vector t0
+* - const polyvecl *s1: pointer to output vector s1
+* - const polyveck *s2: pointer to output vector s2
+* - uint8_t sk[]: byte array containing bit-packed sk
+**************************************************/
+void unpack_sk(uint8_t rho[SEEDBYTES],
+ uint8_t tr[SEEDBYTES],
+ uint8_t key[SEEDBYTES],
+ polyveck *t0,
+ polyvecl *s1,
+ polyveck *s2,
+ const uint8_t sk[CRYPTO_SECRETKEYBYTES])
+{
+ unsigned int i;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ rho[i] = sk[i];
+ sk += SEEDBYTES;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ key[i] = sk[i];
+ sk += SEEDBYTES;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ tr[i] = sk[i];
+ sk += SEEDBYTES;
+
+ for(i=0; i < L; ++i)
+ polyeta_unpack(&s1->vec[i], sk + i*POLYETA_PACKEDBYTES);
+ sk += L*POLYETA_PACKEDBYTES;
+
+ for(i=0; i < K; ++i)
+ polyeta_unpack(&s2->vec[i], sk + i*POLYETA_PACKEDBYTES);
+ sk += K*POLYETA_PACKEDBYTES;
+
+ for(i=0; i < K; ++i)
+ polyt0_unpack(&t0->vec[i], sk + i*POLYT0_PACKEDBYTES);
+}
+
+/*************************************************
+* Name: pack_sig
+*
+* Description: Bit-pack signature sig = (c, z, h).
+*
+* Arguments: - uint8_t sig[]: output byte array
+* - const uint8_t *c: pointer to challenge hash length SEEDBYTES
+* - const polyvecl *z: pointer to vector z
+* - const polyveck *h: pointer to hint vector h
+**************************************************/
+void pack_sig(uint8_t sig[CRYPTO_BYTES],
+ const uint8_t c[SEEDBYTES],
+ const polyvecl *z,
+ const polyveck *h)
+{
+ unsigned int i, j, k;
+
+ for(i=0; i < SEEDBYTES; ++i)
+ sig[i] = c[i];
+ sig += SEEDBYTES;
+
+ for(i = 0; i < L; ++i)
+ polyz_pack(sig + i*POLYZ_PACKEDBYTES, &z->vec[i]);
+ sig += L*POLYZ_PACKEDBYTES;
+
+ /* Encode h */
+ for(i = 0; i < OMEGA + K; ++i)
+ sig[i] = 0;
+
+ k = 0;
+ for(i = 0; i < K; ++i) {
+ for(j = 0; j < N; ++j)
+ if(h->vec[i].coeffs[j] != 0)
+ sig[k++] = j;
+
+ sig[OMEGA + i] = k;
+ }
+}
+
+/*************************************************
+* Name: unpack_sig
+*
+* Description: Unpack signature sig = (c, z, h).
+*
+* Arguments: - uint8_t *c: pointer to output challenge hash
+* - polyvecl *z: pointer to output vector z
+* - polyveck *h: pointer to output hint vector h
+* - const uint8_t sig[]: byte array containing
+* bit-packed signature
+*
+* Returns 1 in case of malformed signature; otherwise 0.
+**************************************************/
+int unpack_sig(uint8_t c[SEEDBYTES],
+ polyvecl *z,
+ polyveck *h,
+ const uint8_t sig[CRYPTO_BYTES])
+{
+ unsigned int i, j, k;
+
+ for(i = 0; i < SEEDBYTES; ++i)
+ c[i] = sig[i];
+ sig += SEEDBYTES;
+
+ for(i = 0; i < L; ++i)
+ polyz_unpack(&z->vec[i], sig + i*POLYZ_PACKEDBYTES);
+ sig += L*POLYZ_PACKEDBYTES;
+
+ /* Decode h */
+ k = 0;
+ for(i = 0; i < K; ++i) {
+ for(j = 0; j < N; ++j)
+ h->vec[i].coeffs[j] = 0;
+
+ if(sig[OMEGA + i] < k || sig[OMEGA + i] > OMEGA)
+ return 1;
+
+ for(j = k; j < sig[OMEGA + i]; ++j) {
+ /* Coefficients are ordered for strong unforgeability */
+ if(j > k && sig[j] <= sig[j-1]) return 1;
+ h->vec[i].coeffs[sig[j]] = 1;
+ }
+
+ k = sig[OMEGA + i];
+ }
+
+ /* Extra indices are zero for strong unforgeability */
+ for(j = k; j < OMEGA; ++j)
+ if(sig[j])
+ return 1;
+
+ return 0;
+}