Home > Research > Code-based cryptography > Code-based cryptosystems : implementations > Implementation of code-based zero-knowledge identification schemes

Implementation of code-based zero-knowledge identification schemes

Tuesday 19 April 2011, by Cayrel, Felix Günther and Holger Rother, Gerhard Hoffman

In the context of the Cryptography Lab in the winter term 2010/2011, our task was to implement three different code-based zero-knowledge identification schemes, namely the ones proposed by Stern in "A new identification scheme based on syndrome decoding" in 1993, Véron in "Improved identification schemes based on error-correcting codes" in 1996, and Cayrel, Véron, and El Yousfi in "A zero-knowledge identification scheme based on the q-ary Syndrome Decoding problem" in 2010.

We implemented these three schemes in C and Java.

This article gives a brief overview over the implementation including some timing results; a detailed report of our work as well as the complete source code are attached.

General Implementation Aspects

There are separated, stand-alone implementations for each of the three identification schemes. They all contain

 the Fast Syndrome-Based hash function
 a pseudorandom number generator based on the construction of Fischer and Stern
 a randomly chosen permutation over vectors of length n

Furthermore, the implementations allow for choosing one of the following matrix types:

 random matrix: the whole matrix (resp. the right block A of a matrix I|A) is chosen at random
 quasi-cyclic matrix: the first line of A (in I|A) is chosen at random and then shifted to produce the whole matrix
 quasi-dyadic matrix: the first line of A (in I|A) is chosen at random and then permuted for the other lines of A according to the quasi-dyadic scheme

Quasi-cyclic and quasi-dyadic matrices allow for a much smaller public key and lower storage overhead while introducing only little higher amount of computation overhead.

C Implementation

You find the code of the C implementation attached as stern_C-code.zip,
veron_C-code.zip resp. cayrel_C-code.zip for the three schemes. In the following we give a short overview over the timing
results.

Timing Results

The tables below show our timing results for all three schemes each with all three matrix types, depending on the security parameter n and using a hash length of 160 bits. The results are shown for one round and a complete identification in 28 rounds for Stern and Véron (for 28 rounds the cheating probability is less than 2^-16) and 16 rounds for Cayrel et al. (for the same security level).

Stern Timing Results
security level 2^40 2^107
n, r, w: 1024, 512, 32 1024, 512, 128
one round 28 rounds one round 28 rounds
Random 12.0ms 336.0ms 156.9ms 4393.2ms
Quasi-Cyclic 14.6ms 408.8ms 156.3ms 4376.4ms
Quasi-Dyadic 11.1ms 310.8ms 135.7ms 3799.6 ms
Véron Timing Results
security level 2^40 2^107
n, r, w: 1024, 512, 32 1024, 512, 128
one round 28 rounds one round 28 rounds
Random 15ms 420.0ms 144.9ms 4057.2ms
Quasi-Cyclic 15.7ms 439.6ms 154.8ms 4334.4ms
Quasi-Dyadic 12.3ms 344.4ms 135.4ms 3781.2ms
Cayrel et al. Timing Results
security level 2^73 2^143
n, r, w, q: 128, 64, 49, 256 256, 128, 97, 256
one round 16 rounds one round 16 rounds
Random 5.8ms 92.8ms 16.8ms 268.8ms
Quasi-Cyclic 9.1ms 145.6ms 23.3ms 372.8ms
Quasi-Dyadic 3.3ms 52.8ms 11.5ms 184.0ms

New C Implementation

In total, six different schemes have been implemented:
the Stern, Veron and CVE identification schemes and the corresponding signature schemes based on the Fiat-Shamir transform.
You find the code of the the new implementation attached as stern_c.tgz,
cve_c.tgz,
veron_c.tgz,

The implementation assumes that the dimensions of the matrices are a multiple of 64. The public keys G and H are given in systematic form, i.e. G = I_k and H = I_n-k respectively, where only the redundant part R is used.

In the quasi-cyclic and quasi-dyadic cases, the matrices G and H consist of cyclic and dyadic submatrices of size 64x64, because 64 is the natural number to use on a 64-bit machine.

For the generation of random vectors and hash values used in our identification protocols we deployed Keccak (http://keccak.noekeon.org) one of the last five remaining candidates of the NIST hash function competition for SHA-3. We have chose Keccak, because it can be used as a hash function and as stream cipher at the same time. But note that it can be replaced by any other suitable scheme providing the necessary functionality.

Finally, all the tests have been carried out only on an Intel(R) Core(TM)2 Duo CPU E8400@3.00GHz machine running Linux 2.6.32-21 (Ubuntu). The implementation has been compiled with gcc 4.4.3, it assumes a 64-bit architecture.

Stern scheme
This scheme uses a binary parity check matrix H = I_n-k of size r x n, where r = n-k and k = n/2.

Due to the row-major order of C, the product sH^T is more efficient as Hs^T (s a binary vector of length n). Hence, the implementation uses the transposed matrix H^T instead of H.

Stern timing results
Matrix Type Dim: nxr Weight 1 rnd [ms] 28 rnds [ms] Sec
Random 768x384 76 0.042 1.047 2^80
QC 768x384 76 0.038 0.959 2^80
QD 768x384 76 0.078 1.506 2^80

Veron scheme
This scheme uses a binary generator matrix G = I_k of dimensions kxn, where k = n/2. Again, in the quasi-cyclic and quasi-dyadic case, the cyclic and dyadic submatrices have a size of 64x64 bits. As in Stern, if G is quasi-cyclic or quasi-dyadic, then the submatrix R would consist of 36 cyclic or dyadic submatrices of size 64x64 bits.

Veron timing results
Matrix Type Dim: nxr Weight 1 rnd [ms] 28 rnds [ms] Sec
Random 768x384 76 0.053 0.896 2^80
QC 768x384 76 0.049 0.962 2^80
QD 768x384 76 0.074 1.494 2^80

CVE scheme
It uses a parity check matrix H of size rxn over Fq, where q=2^m,
1 <= m <= 16, r = n-k and k = n/2. As in the Stern scheme, the implementation uses the transposed matrix H^T instead of H.

Again, if H is quasi-cyclic or quasi-dyadic, then the submatrix R would consist of 36 cyclic or dyadic submatrices of 64x64 field elements.

The matrix size is always measured in numbers of field elements. Each field element occupies invariably 2 bytes of memory. Strictly speaking, this would be necessary only in the case m=16. However, using only the necessary bits would complicate the code and slow down the computation. In environments in which memory is a very valuable resource, this fact had to be taken into account.

For the measurements we used m=8, q=256.

CVE timing results
Matrix Type Dim: nxr q Weight 1 rnd [ms] 16 rnds [ms] Sec
Random 144x72 256 55 0.035 0.580 2^81
QC 144x72 256 55 0.072 0.710 2^81
QD 144x72 256 55 0.054 0.678 2^81

Signature schemes based on Fiat-Shamir transform
Using the Fiat-Shamir transform, one can transform identification schemes to signature schemes.

Note that the signer and verifier parts are always located in the same executable, thus the two parts can communicate in almost no time. In reality, they would reside on different machines, such that additional costs over some communication link had to be taken into account.

Stern signature scheme timings
For the Stern timing results we give the time for one round, separated in signing and verification time (s/v). The size of the message to be signed is given in MiB.

Stern timing results
Matrix Type Dim: nxr Weight s [ms] v [ms] Msg. [MiB] Sec
Random 768x384 76 5.754 5.445 1 2^80
768x384 76 56.879 56.475 10 2^80
768x384 76 142.215 139.814 25 2^80
QC 768x384 76 5.690 5.405 1 2^80
768x384 76 12.580 11.773 10 2^80
768x384 76 142.359 139.844 25 2^80
QD 768x384 76 5.706 5.407 1 2^80
768x384 76 56.877 56.389 10 2^80
768x384 76 142.155 139.954 25 2^80

Veron signature scheme timings

Veron timing results
Matrix Type Dim: nxr Weight s [ms] v [ms] Msg. [MiB] Sec
Random 768x384 76 5.548 5.567 1 2^80
768x384 76 55.984 56.533 10 2^80
768x384 76 140.107 141.926 25 2^80
QC 768x384 76 5.493 5.594 1 2^80
768x384 76 55.929 56.966 10 2^80
768x384 76 139.998 141.599 25 2^80
QD 768x384 76 5.517 5.553 1 2^80
768x384 76 56.485 56.402 10 2^80
768x384 76 140.346 141.743 25 2^80

CVE signature scheme timings

CVE timing results
Matrix Type Dim: nxr Weight s [ms] v [ms] Msg. [MiB] Sec
Random 144x72 55 10.378 9.854 1 2^80
144x72 55 111.543 108.720 10 2^80
144x72 55 278.473 274.903 25 2^80
QC 144x72 55 10.516 9.829 1 2^80
144x72 55 110.722 109.276 10 2^80
144x72 55 278.949 274.194 25 2^80
QD 144x72 55 10.400 9.962 1 2^80
144x72 55 110.866 109.151 10 2^80
144x72 55 278.591 274.906 25 2^80

Remarks
The signature size (an average value of several runs over 28 resp. 16 rounds. for Stern and Veron is about 60.000 bytes and for CVE about 15.000 bytes.

The runtime is dominated by Keccak creating random vectors u[0],...,u[rounds-1]
before entering the loop of 28 resp. 16 rounds, which could also be confirmed
profiling the implementation directly with gprof (the profiler
contained in gcc).

Java Implementation

You find the code of the Java implementation attached as stern_Java.zip, veron_Java.zip resp. cayrel_Java.zip for the three schemes. In the following we give a short overview over the timing results.

Timing Results

The tables below show our timing results for all three schemes each with all three matrix types, depending on the security parameter n and using a hash length of 160 bits. The results are shown for one round and a complete identification in 28 rounds for Stern and Véron (for 28 rounds the cheating probability is less than 2^-16) and 16 rounds for Cayrel et al. (for the same security level).

Stern Timing Results
security level 2^40 2^107
n, r, w: 1024, 512, 32 1024, 512, 128
one round 28 rounds one round 28 rounds
Random 123.38ms 3454.38ms 131.12ms 3671.50ms
Quasi-Cyclic 145.69ms 4079.50ms 184.25ms 5158.99ms
Quasi-Dyadic 189.50ms 5306.08ms 309.84ms 8675.53ms
Véron Timing Results
security level 2^40 2^107
n, r, w: 1024, 512, 32 1024, 512, 128
one round 28 rounds one round 28 rounds
Random 140.68ms 3939.08ms 149.12ms 4175.47ms
Quasi-Cyclic 156.84ms 4391.60ms 199.63ms 5589.79ms
Quasi-Dyadic 189.29ms 5300.05ms 309.62ms 8669.28ms
Cayrel et al. Timing Results
security level 2^73 2^143
n, r, w, q: 128, 64, 49, 256 256, 128, 97, 256
one round 16 rounds one round 16 rounds
Random 84.07ms 1345.07ms 91.85ms 1469.63ms
Quasi-Cyclic 107.13ms 1714.02ms 129.54ms 2072.68ms
Quasi-Dyadic 147.29ms 2356.59ms 207.24ms 3315.92ms