00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include "sizes.h"
00024 #include "dicho.h"
00025 #include "randomize.h"
00026
00027 extern precomp_t cwdata;
00028
00029
00030
00031 void vec_concat(unsigned long* x, unsigned long* a, unsigned long* b)
00032 {
00033 int i, j, k, l;
00034
00035 if (DIMENSION % 8 == 0) {
00036 memcpy(x, a, BITS_TO_BYTES(DIMENSION));
00037 memcpy(((unsigned char *) x) + BITS_TO_BYTES(DIMENSION), b, BITS_TO_BYTES(CODIMENSION));
00038 }
00039 else {
00040 i = DIMENSION - BIT_SIZE_OF_LONG * (DIMENSION / BIT_SIZE_OF_LONG);
00041 j = BIT_SIZE_OF_LONG - i;
00042 l = DIMENSION / BIT_SIZE_OF_LONG;
00043 memcpy(x, a, sizeof (long) * (DIMENSION / BIT_SIZE_OF_LONG));
00044 x[l] = a[l] & ((1 << i) - 1);
00045
00046 for (k = 0; k < CODIMENSION / BIT_SIZE_OF_LONG; ++k) {
00047 x[l] ^= b[k] << i;
00048 ++l;
00049 x[l] = b[k] >> j;
00050 }
00051 x[l] ^= b[k] << i;
00052 }
00053 }
00054
00055 void addto(unsigned long * a, unsigned long * b) {
00056 int i;
00057
00058 for (i = 0; i < BITS_TO_LONG(CODIMENSION); ++i)
00059 a[i] ^= b[i];
00060 }
00061
00062 int encrypt_block(unsigned char *ciphertext, unsigned char *cleartext, const unsigned char * pk)
00063 {
00064 int i, j;
00065 unsigned long cR[BITS_TO_LONG(CODIMENSION)], *pt;
00066 int e[ERROR_WEIGHT];
00067 unsigned char c, d;
00068
00069 pt = (unsigned long *) pk;
00070 memset(cR, 0, BITS_TO_LONG(CODIMENSION) * sizeof(long));
00071 for (i = 0; i < DIMENSION / 8; ++i) {
00072 for (j = 0; j < 8; ++j) {
00073 if (cleartext[i] & (1 << j))
00074 addto(cR, pt);
00075 pt += BITS_TO_LONG(CODIMENSION);
00076 }
00077 }
00078 for (j = 0; j < DIMENSION % 8 ; ++j) {
00079 if (cleartext[i] & (1 << j))
00080 addto(cR, pt);
00081 pt += BITS_TO_LONG(CODIMENSION);
00082 }
00083
00084
00085
00086 i = dicho_b2cw(cleartext, e,
00087 DIMENSION, ERROR_SIZE,
00088 LOG_LENGTH, ERROR_WEIGHT, cwdata);
00089
00090
00091
00092 if (i < 0)
00093 return -1;
00094
00095
00096 vec_concat((unsigned long *) ciphertext, (unsigned long *) cleartext, cR);
00097
00098
00099 for (i = 0; i < NB_ERRORS; i++) {
00100 ciphertext[e[i] / 8] ^= (1 << (e[i] % 8));
00101 }
00102
00103 return 1;
00104 }
00105
00106
00107
00108 int encrypt_block_ss(unsigned char *ciphertext, unsigned char *message, const unsigned char * pk)
00109 {
00110 unsigned char cleartext[CLEARTEXT_LENGTH];
00111
00112 randomize(cleartext, message);
00113 return encrypt_block(ciphertext, cleartext, pk);
00114 }