Rizin
unix-like reverse engineering framework and cli tools
crypto_serpent_algo.c File Reference

Go to the source code of this file.

Functions

static void rotr (ut32 *x, int s)
 
static void rotl (ut32 *x, int s)
 
static ut8 apply_sbox (int si, ut8 x)
 
static ut8 apply_sbox_inv (int si, ut8 x)
 
static ut8 get_bit (int i, ut32 input)
 
void apply_IP (ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
 
void apply_FP (ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
 
void serpent_keyschedule (const serpent_state_t *st, ut32 subkeys[NB_SUBKEYS *DW_BY_BLOCK])
 
void apply_xor (ut32 block[DW_BY_BLOCK], ut32 subkey[DW_BY_BLOCK])
 
void apply_permut (ut32 block[DW_BY_BLOCK])
 
void apply_permut_inv (ut32 block[DW_BY_BLOCK])
 
void apply_round (int round, ut32 block[DW_BY_BLOCK], ut32 subkeys[DW_BY_BLOCK *NB_SUBKEYS])
 
void apply_round_inv (int round, ut32 block[DW_BY_BLOCK], ut32 subkeys[DW_BY_BLOCK *NB_SUBKEYS])
 
void serpent_encrypt (serpent_state_t *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
 
void serpent_decrypt (serpent_state_t *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
 

Variables

static const ut8 S [][16]
 
static const ut8 Sinv [][16]
 
static const ut8 IPTable []
 
static const ut8 FPTable []
 

Function Documentation

◆ apply_FP()

void apply_FP ( ut32  in[DW_BY_BLOCK],
ut32  out[DW_BY_BLOCK] 
)

Definition at line 84 of file crypto_serpent_algo.c.

84  {
85  int index;
86  int i;
87  for (i = 0; i < DW_BY_BLOCK * 32; i++) {
88  index = FPTable[i];
89  out[i / 32] ^= (-(ut32)get_bit(index % 32, in[index / 32]) ^ out[i / 32]) & (1 << (i & 0x1f));
90  }
91 }
lzma_index ** i
Definition: index.h:629
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
static ut8 get_bit(int i, ut32 input)
static const ut8 FPTable[]
#define DW_BY_BLOCK
uint32_t ut32

References DW_BY_BLOCK, FPTable, get_bit(), i, in, and out.

Referenced by apply_permut(), apply_permut_inv(), serpent_decrypt(), and serpent_encrypt().

◆ apply_IP()

void apply_IP ( ut32  in[DW_BY_BLOCK],
ut32  out[DW_BY_BLOCK] 
)

Definition at line 75 of file crypto_serpent_algo.c.

75  {
76  int index;
77  int i;
78  for (i = 0; i < DW_BY_BLOCK * 32; i++) {
79  index = IPTable[i];
80  out[i / 32] ^= (-(ut32)get_bit(index % 32, in[index / 32]) ^ out[i / 32]) & (1 << (i & 0x1f));
81  }
82 }
static const ut8 IPTable[]

References DW_BY_BLOCK, get_bit(), i, in, IPTable, and out.

Referenced by apply_permut(), apply_permut_inv(), serpent_decrypt(), serpent_encrypt(), and serpent_keyschedule().

◆ apply_permut()

void apply_permut ( ut32  block[DW_BY_BLOCK])

Definition at line 145 of file crypto_serpent_algo.c.

145  {
146  ut32 tmp_block[DW_BY_BLOCK] = { 0 };
147  apply_FP(block, tmp_block);
148  rotl(tmp_block + 0, 13);
149  rotl(tmp_block + 2, 3);
150  tmp_block[1] ^= tmp_block[0] ^ tmp_block[2];
151  tmp_block[3] ^= tmp_block[2] ^ (tmp_block[0] << 3);
152  rotl(tmp_block + 1, 1);
153  rotl(tmp_block + 3, 7);
154  tmp_block[0] ^= tmp_block[1] ^ tmp_block[3];
155  tmp_block[2] ^= tmp_block[3] ^ (tmp_block[1] << 7);
156  rotl(tmp_block + 0, 5);
157  rotl(tmp_block + 2, 22);
158  apply_IP(tmp_block, block);
159 }
void apply_IP(ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
void apply_FP(ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
static void rotl(ut32 *x, int s)

References apply_FP(), apply_IP(), DW_BY_BLOCK, and rotl().

Referenced by apply_round().

◆ apply_permut_inv()

void apply_permut_inv ( ut32  block[DW_BY_BLOCK])

Definition at line 161 of file crypto_serpent_algo.c.

161  {
162  ut32 tmp_block[DW_BY_BLOCK] = { 0 };
163  apply_FP(block, tmp_block);
164  rotr(tmp_block + 0, 5);
165  rotr(tmp_block + 2, 22);
166  tmp_block[2] ^= tmp_block[3] ^ (tmp_block[1] << 7);
167  tmp_block[0] ^= tmp_block[1] ^ tmp_block[3];
168  rotr(tmp_block + 3, 7);
169  rotr(tmp_block + 1, 1);
170  tmp_block[3] ^= tmp_block[2] ^ (tmp_block[0] << 3);
171  tmp_block[1] ^= tmp_block[0] ^ tmp_block[2];
172  rotr(tmp_block + 2, 3);
173  rotr(tmp_block + 0, 13);
174  apply_IP(tmp_block, block);
175 }
static void rotr(ut32 *x, int s)

References apply_FP(), apply_IP(), DW_BY_BLOCK, and rotr().

Referenced by apply_round_inv().

◆ apply_round()

void apply_round ( int  round,
ut32  block[DW_BY_BLOCK],
ut32  subkeys[DW_BY_BLOCK *NB_SUBKEYS] 
)

Definition at line 177 of file crypto_serpent_algo.c.

178  {
179  int i, j;
180 
181  apply_xor(block, subkeys + 4 * round);
182 
183  for (i = 0; i < DW_BY_BLOCK; i++) {
184  ut32 res = 0;
185  for (j = 0; j < 8; j++) {
186  res |= apply_sbox(round % 8, (block[i] >> 4 * j) & 0xf) << 4 * j;
187  }
188  block[i] = res;
189  }
190 
191  if (round == NB_ROUNDS - 1) {
192  apply_xor(block, subkeys + 4 * (round + 1));
193  } else {
194  apply_permut(block);
195  }
196 }
static ut8 apply_sbox(int si, ut8 x)
void apply_xor(ut32 block[DW_BY_BLOCK], ut32 subkey[DW_BY_BLOCK])
void apply_permut(ut32 block[DW_BY_BLOCK])
#define NB_ROUNDS

References apply_permut(), apply_sbox(), apply_xor(), DW_BY_BLOCK, i, and NB_ROUNDS.

Referenced by serpent_encrypt().

◆ apply_round_inv()

void apply_round_inv ( int  round,
ut32  block[DW_BY_BLOCK],
ut32  subkeys[DW_BY_BLOCK *NB_SUBKEYS] 
)

Definition at line 198 of file crypto_serpent_algo.c.

199  {
200  if (round == NB_ROUNDS - 1) {
201  apply_xor(block, subkeys + 4 * (round + 1));
202  } else {
203  apply_permut_inv(block);
204  }
205 
206  int i, j;
207  ut32 res;
208 
209  for (i = 0; i < DW_BY_BLOCK; i++) {
210  res = 0;
211  for (j = 0; j < 8; j++) {
212  res |= apply_sbox_inv(round % 8, (block[i] >> 4 * j) & 0xf) << 4 * j;
213  }
214  block[i] = res;
215  }
216 
217  apply_xor(block, subkeys + 4 * round);
218 }
static ut8 apply_sbox_inv(int si, ut8 x)
void apply_permut_inv(ut32 block[DW_BY_BLOCK])

References apply_permut_inv(), apply_sbox_inv(), apply_xor(), DW_BY_BLOCK, i, and NB_ROUNDS.

Referenced by serpent_decrypt().

◆ apply_sbox()

static ut8 apply_sbox ( int  si,
ut8  x 
)
inlinestatic

Definition at line 60 of file crypto_serpent_algo.c.

60  {
61  x = S[si][x & 0xf];
62  return x;
63 }
si
static const ut8 S[][16]
int x
Definition: mipsasm.c:20

References S, si, and x.

Referenced by apply_round(), and serpent_keyschedule().

◆ apply_sbox_inv()

static ut8 apply_sbox_inv ( int  si,
ut8  x 
)
inlinestatic

Definition at line 65 of file crypto_serpent_algo.c.

65  {
66  x = Sinv[si][x & 0xf];
67  return x;
68 }
static const ut8 Sinv[][16]

References si, Sinv, and x.

Referenced by apply_round_inv().

◆ apply_xor()

void apply_xor ( ut32  block[DW_BY_BLOCK],
ut32  subkey[DW_BY_BLOCK] 
)

Definition at line 138 of file crypto_serpent_algo.c.

138  {
139  int i;
140  for (i = 0; i < DW_BY_BLOCK; i++) {
141  block[i] ^= subkey[i];
142  }
143 }

References DW_BY_BLOCK, and i.

Referenced by apply_round(), and apply_round_inv().

◆ get_bit()

static ut8 get_bit ( int  i,
ut32  input 
)
inlinestatic

Definition at line 70 of file crypto_serpent_algo.c.

70  {
71  rz_return_val_if_fail(i < 32, 0);
72  return (input >> i) & 1;
73 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)

References i, input(), and rz_return_val_if_fail.

Referenced by apply_FP(), apply_IP(), and serpent_keyschedule().

◆ rotl()

static void rotl ( ut32 x,
int  s 
)
inlinestatic

Definition at line 55 of file crypto_serpent_algo.c.

55  {
56  *x = (*x << s) | (*x >> (32 - s));
57 }
static RzSocket * s
Definition: rtr.c:28

References s, and x.

Referenced by apply_permut(), and serpent_keyschedule().

◆ rotr()

static void rotr ( ut32 x,
int  s 
)
inlinestatic

Definition at line 51 of file crypto_serpent_algo.c.

51  {
52  *x = (*x >> s) | (*x << (32 - s));
53 }

References s, and x.

Referenced by apply_permut_inv().

◆ serpent_decrypt()

void serpent_decrypt ( serpent_state_t st,
ut32  in[DW_BY_BLOCK],
ut32  out[DW_BY_BLOCK] 
)

Definition at line 235 of file crypto_serpent_algo.c.

236  {
237  int i;
238  ut32 subkeys[DW_BY_BLOCK * NB_SUBKEYS] = { 0 };
239  ut32 tmp_block[DW_BY_BLOCK] = { 0 };
240 
241  serpent_keyschedule(st, subkeys);
242 
243  apply_IP(in, tmp_block);
244  for (i = NB_ROUNDS - 1; i >= 0; i--) {
245  apply_round_inv(i, tmp_block, subkeys);
246  }
247  apply_FP(tmp_block, out);
248 }
void apply_round_inv(int round, ut32 block[DW_BY_BLOCK], ut32 subkeys[DW_BY_BLOCK *NB_SUBKEYS])
void serpent_keyschedule(const serpent_state_t *st, ut32 subkeys[NB_SUBKEYS *DW_BY_BLOCK])
#define NB_SUBKEYS

References apply_FP(), apply_IP(), apply_round_inv(), DW_BY_BLOCK, i, in, NB_ROUNDS, NB_SUBKEYS, out, and serpent_keyschedule().

Referenced by update().

◆ serpent_encrypt()

void serpent_encrypt ( serpent_state_t st,
ut32  in[DW_BY_BLOCK],
ut32  out[DW_BY_BLOCK] 
)

Definition at line 220 of file crypto_serpent_algo.c.

221  {
222  int i;
223  ut32 subkeys[DW_BY_BLOCK * NB_SUBKEYS] = { 0 };
224  ut32 tmp_block[DW_BY_BLOCK] = { 0 };
225 
226  serpent_keyschedule(st, subkeys);
227 
228  apply_IP(in, tmp_block);
229  for (i = 0; i < NB_ROUNDS; i++) {
230  apply_round(i, tmp_block, subkeys);
231  }
232  apply_FP(tmp_block, out);
233 }
void apply_round(int round, ut32 block[DW_BY_BLOCK], ut32 subkeys[DW_BY_BLOCK *NB_SUBKEYS])

References apply_FP(), apply_IP(), apply_round(), DW_BY_BLOCK, i, in, NB_ROUNDS, NB_SUBKEYS, out, and serpent_keyschedule().

Referenced by update().

◆ serpent_keyschedule()

void serpent_keyschedule ( const serpent_state_t st,
ut32  subkeys[NB_SUBKEYS *DW_BY_BLOCK] 
)

Definition at line 93 of file crypto_serpent_algo.c.

93  {
94  rz_return_if_fail((st->key_size == 128) || (st->key_size == 192) || (st->key_size == 256));
95 
96  ut32 tmpkeys[DW_BY_BLOCK * NB_SUBKEYS + DW_BY_USERKEY] = { 0 };
97  const ut32 phi = 0x9e3779b9;
98  int si;
99  ut8 in, out;
100  int i, j, l;
101 
102  for (i = 0; i < st->key_size / 32; i++) {
103  tmpkeys[i] = st->key[i];
104  }
105 
106  // Padding key
107  if (st->key_size != 256) {
108  tmpkeys[st->key_size / 32] = 1;
109  }
110 
112  tmpkeys[i] = tmpkeys[i - 8] ^ tmpkeys[i - 5] ^ tmpkeys[i - 3] ^ tmpkeys[i - 1] ^ phi ^ (i - 8);
113  rotl(tmpkeys + i, 11);
114  }
115 
116  // Applying sbox for subkey i
117  for (i = 0; i < NB_SUBKEYS; i++) {
118  si = (32 + 3 - i) % 8;
119 
120  // Iterates over all nibbles of the subkey i
121  for (j = 0; j < NIBBLES_BY_SUBKEY; j++) {
122  in = get_bit(j, tmpkeys[0 + DW_BY_BLOCK * i + DW_BY_USERKEY]) | get_bit(j, tmpkeys[1 + DW_BY_BLOCK * i + DW_BY_USERKEY]) << 1 | get_bit(j, tmpkeys[2 + DW_BY_BLOCK * i + DW_BY_USERKEY]) << 2 | get_bit(j, tmpkeys[3 + DW_BY_BLOCK * i + DW_BY_USERKEY]) << 3;
123  out = apply_sbox(si, in);
124  for (l = 0; l < DW_BY_BLOCK; l++) {
125  subkeys[l + DW_BY_BLOCK * i] |= get_bit(l, (ut32)out) << j;
126  }
127  }
128  }
129 
130  // Apply IP on every subkey
131  for (i = 0; i < NB_SUBKEYS; i++) {
132  apply_IP(&subkeys[i * DW_BY_BLOCK], &tmpkeys[DW_BY_USERKEY + i * DW_BY_BLOCK]);
133  }
134 
135  memcpy(subkeys, tmpkeys + DW_BY_USERKEY, 132 * sizeof(ut32));
136 }
#define DW_BY_USERKEY
#define NIBBLES_BY_SUBKEY
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100

References apply_IP(), apply_sbox(), DW_BY_BLOCK, DW_BY_USERKEY, get_bit(), i, in, serpent_state::key, serpent_state::key_size, memcpy(), NB_SUBKEYS, NIBBLES_BY_SUBKEY, out, rotl(), rz_return_if_fail, and si.

Referenced by serpent_decrypt(), and serpent_encrypt().

Variable Documentation

◆ FPTable

const ut8 FPTable[]
static
Initial value:
= {
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61,
65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125,
2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62,
66, 70, 74, 78, 82, 86, 90, 94, 98, 102, 106, 110, 114, 118, 122, 126,
3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63,
67, 71, 75, 79, 83, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127
}

Definition at line 40 of file crypto_serpent_algo.c.

Referenced by apply_FP().

◆ IPTable

const ut8 IPTable[]
static
Initial value:
= {
0, 32, 64, 96, 1, 33, 65, 97, 2, 34, 66, 98, 3, 35, 67, 99,
4, 36, 68, 100, 5, 37, 69, 101, 6, 38, 70, 102, 7, 39, 71, 103,
8, 40, 72, 104, 9, 41, 73, 105, 10, 42, 74, 106, 11, 43, 75, 107,
12, 44, 76, 108, 13, 45, 77, 109, 14, 46, 78, 110, 15, 47, 79, 111,
16, 48, 80, 112, 17, 49, 81, 113, 18, 50, 82, 114, 19, 51, 83, 115,
20, 52, 84, 116, 21, 53, 85, 117, 22, 54, 86, 118, 23, 55, 87, 119,
24, 56, 88, 120, 25, 57, 89, 121, 26, 58, 90, 122, 27, 59, 91, 123,
28, 60, 92, 124, 29, 61, 93, 125, 30, 62, 94, 126, 31, 63, 95, 127
}

Definition at line 29 of file crypto_serpent_algo.c.

Referenced by apply_IP().

◆ S

const ut8 S[][16]
static
Initial value:
= {
{ 3, 8, 15, 1, 10, 6, 5, 11, 14, 13, 4, 2, 7, 0, 9, 12 },
{ 15, 12, 2, 7, 9, 0, 5, 10, 1, 11, 14, 8, 6, 13, 3, 4 },
{ 8, 6, 7, 9, 3, 12, 10, 15, 13, 1, 14, 4, 0, 11, 5, 2 },
{ 0, 15, 11, 8, 12, 9, 6, 3, 13, 1, 2, 4, 10, 7, 5, 14 },
{ 1, 15, 8, 3, 12, 0, 11, 6, 2, 5, 4, 10, 9, 14, 7, 13 },
{ 15, 5, 2, 11, 4, 10, 9, 12, 0, 3, 14, 8, 13, 6, 7, 1 },
{ 7, 2, 12, 5, 8, 4, 6, 11, 14, 9, 1, 15, 13, 3, 10, 0 },
{ 1, 13, 15, 0, 14, 8, 2, 11, 7, 4, 12, 10, 9, 3, 5, 6 },
}

Definition at line 7 of file crypto_serpent_algo.c.

Referenced by apply_sbox().

◆ Sinv

const ut8 Sinv[][16]
static
Initial value:
= {
{ 13, 3, 11, 0, 10, 6, 5, 12, 1, 14, 4, 7, 15, 9, 8, 2 },
{ 5, 8, 2, 14, 15, 6, 12, 3, 11, 4, 7, 9, 1, 13, 10, 0 },
{ 12, 9, 15, 4, 11, 14, 1, 2, 0, 3, 6, 13, 5, 8, 10, 7 },
{ 0, 9, 10, 7, 11, 14, 6, 13, 3, 5, 12, 2, 4, 8, 15, 1 },
{ 5, 0, 8, 3, 10, 9, 7, 14, 2, 12, 11, 6, 4, 15, 13, 1 },
{ 8, 15, 2, 9, 4, 1, 13, 14, 11, 6, 5, 3, 7, 12, 10, 0 },
{ 15, 10, 1, 13, 5, 3, 6, 0, 4, 9, 14, 7, 2, 12, 8, 11 },
{ 3, 0, 6, 13, 9, 14, 15, 8, 5, 12, 11, 7, 10, 1, 4, 2 },
}

Definition at line 18 of file crypto_serpent_algo.c.

Referenced by apply_sbox_inv().