Skip to content
Snippets Groups Projects
Commit 478484e6 authored by Niels Möller's avatar Niels Möller
Browse files

* blowfish.c (initial_ctx): Arrange constants into a struct, to

simplify key setup.
(F): Deleted all but one definitions of the F function/macro.
Added a context argument, and use that to find the subkeys.
(R): Added context argument, and use that to find the subkeys.
(blowfish_set_key): Some simplification.

(encrypt): Deleted code for non-standard number of rounds. Deleted
a bunch of local variables. Using the context pointer for
everything should consume less registers.
(decrypt): Likewise.

Rev: src/nettle/blowfish.c:1.3
parent 42d7d416
Branches
Tags
No related merge requests found
...@@ -33,10 +33,16 @@ ...@@ -33,10 +33,16 @@
#include "blowfish.h" #include "blowfish.h"
#include "macros.h"
#include <assert.h> #include <assert.h>
/* precomputed S boxes */ /* Initial keysetup state */
static const uint32_t ks0[256] = { static const struct blowfish_ctx
initial_ctx =
{ /* precomputed S boxes */
{
{
0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96, 0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96,
0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16, 0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16,
0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658, 0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658,
...@@ -79,9 +85,8 @@ static const uint32_t ks0[256] = { ...@@ -79,9 +85,8 @@ static const uint32_t ks0[256] = {
0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915, 0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915,
0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F, 0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F,
0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664, 0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664,
0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A }; 0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A
}, {
static const uint32_t ks1[256] = {
0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D, 0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D,
0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1, 0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1,
0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65, 0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65,
...@@ -124,9 +129,8 @@ static const uint32_t ks1[256] = { ...@@ -124,9 +129,8 @@ static const uint32_t ks1[256] = {
0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC, 0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC,
0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD, 0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD,
0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20, 0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20,
0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 }; 0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7
}, {
static const uint32_t ks2[256] = {
0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7, 0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7,
0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF, 0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF,
0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF, 0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF,
...@@ -169,9 +173,8 @@ static const uint32_t ks2[256] = { ...@@ -169,9 +173,8 @@ static const uint32_t ks2[256] = {
0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC, 0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC,
0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8, 0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8,
0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837, 0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837,
0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 }; 0xD79A3234,0x92638212,0x670EFA8E,0x406000E0
}, {
static const uint32_t ks3[256] = {
0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742, 0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742,
0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B, 0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B,
0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79, 0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79,
...@@ -214,215 +217,115 @@ static const uint32_t ks3[256] = { ...@@ -214,215 +217,115 @@ static const uint32_t ks3[256] = {
0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060, 0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060,
0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C, 0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C,
0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F, 0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F,
0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 }; 0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6
}
static const uint32_t ps[_BLOWFISH_ROUNDS+2] = { },
/* p constants */
{
0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0, 0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,
0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C, 0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,
0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B }; 0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B
},
/* Initial value, reset after key is checked. */
BLOWFISH_WEAK_KEY
};
#if _BLOWFISH_ROUNDS != 16 /* It's unfortunate to have to pick the bytes apart in the round
static inline u32 * function. Werner's GNUPG code stored took the address of x, and
function_F( BLOWFISH_context *bc, u32 x ) * then read the individual bytes depending on the endianness. But xr
{ * and xl ought to live in registers, so I'm not sure that really is a
unsigned a, b, c, d; * good way to do it. */
/* FIXME: I don't quite like this hack. It assumes that the byteorder #define F(c, x) \
* is plain big or little endian (and for instance not PDP-ish), and ((( (c->s[0][(x>>24) &0xff] + c->s[1][(x>>16) & 0xff]) \
* that a u32 is exactly 32 bits (while the autoconf stuff only ^ c->s[2][(x>>8) & 0xff]) + c->s[3][x & 0xff]) & 0xffffffff)
* guarantees that it is *at least* 32 bits).
*
* On the other hand, taking the address of x makes it difficult to
* place it in a register, which make me wonder if it will really make
* the code run any faster. */
#if BIG_ENDIAN_HOST
#warning BIG_ENDIAN hack used
a = ((byte*)&x)[0];
b = ((byte*)&x)[1];
c = ((byte*)&x)[2];
d = ((byte*)&x)[3];
#elif LITTLE_ENDIAN_HOST
#warning LITTLE_ENDIAN hack used
a = ((byte*)&x)[3];
b = ((byte*)&x)[2];
c = ((byte*)&x)[1];
d = ((byte*)&x)[0];
#else
a = x >> 24;
b = (x >> 16) & 0xff;
c = (x >> 8) & 0xff;
d = x & 0xff;
#endif
return (((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d]) & 0xffffffff;
}
#endif
#if BIG_ENDIAN_HOST #define R(c, l, r, i) do { l ^= c->p[i]; r ^= F(c, l); } while(0)
#warning BIG_ENDIAN hack used
#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]]) \
^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
#elif LITTLE_ENDIAN_HOST
#warning LITTLE_ENDIAN hack used
#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]]) \
^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
#else
#define F(x) (((( s0[x>>24] + s1[(x>>16) & 0xff]) \
^ s2[(x>>8) & 0xff]) + s3[x & 0xff]) & 0xffffffff)
#endif
#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
static void static void
encrypt(struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr) encrypt(struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr)
{ {
#if _BLOWFISH_ROUNDS == 16 uint32_t xl, xr;
uint32_t xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl; xl = *ret_xl;
xr = *ret_xr; xr = *ret_xr;
p = bc->p; R(bc, xl, xr, 0);
s0 = bc->s0; R(bc, xr, xl, 1);
s1 = bc->s1; R(bc, xl, xr, 2);
s2 = bc->s2; R(bc, xr, xl, 3);
s3 = bc->s3; R(bc, xl, xr, 4);
R(bc, xr, xl, 5);
R( xl, xr, 0); R(bc, xl, xr, 6);
R( xr, xl, 1); R(bc, xr, xl, 7);
R( xl, xr, 2); R(bc, xl, xr, 8);
R( xr, xl, 3); R(bc, xr, xl, 9);
R( xl, xr, 4); R(bc, xl, xr, 10);
R( xr, xl, 5); R(bc, xr, xl, 11);
R( xl, xr, 6); R(bc, xl, xr, 12);
R( xr, xl, 7); R(bc, xr, xl, 13);
R( xl, xr, 8); R(bc, xl, xr, 14);
R( xr, xl, 9); R(bc, xr, xl, 15);
R( xl, xr, 10);
R( xr, xl, 11); xl ^= bc->p[_BLOWFISH_ROUNDS];
R( xl, xr, 12); xr ^= bc->p[_BLOWFISH_ROUNDS+1];
R( xr, xl, 13);
R( xl, xr, 14);
R( xr, xl, 15);
xl ^= p[_BLOWFISH_ROUNDS];
xr ^= p[_BLOWFISH_ROUNDS+1];
*ret_xl = xr; *ret_xl = xr;
*ret_xr = xl; *ret_xr = xl;
#else
uint32_t xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
for(i=0; i < _BLOWFISH_ROUNDS; i++ ) {
xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= p[_BLOWFISH_ROUNDS];
xl ^= p[_BLOWFISH_ROUNDS+1];
*ret_xl = xl;
*ret_xr = xr;
#endif
} }
static void static void
decrypt(struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr ) decrypt(struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr )
{ {
#if _BLOWFISH_ROUNDS == 16 uint32_t xl, xr;
uint32_t xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl; xl = *ret_xl;
xr = *ret_xr; xr = *ret_xr;
p = bc->p;
s0 = bc->s0; R(bc, xl, xr, 17);
s1 = bc->s1; R(bc, xr, xl, 16);
s2 = bc->s2; R(bc, xl, xr, 15);
s3 = bc->s3; R(bc, xr, xl, 14);
R(bc, xl, xr, 13);
R( xl, xr, 17); R(bc, xr, xl, 12);
R( xr, xl, 16); R(bc, xl, xr, 11);
R( xl, xr, 15); R(bc, xr, xl, 10);
R( xr, xl, 14); R(bc, xl, xr, 9);
R( xl, xr, 13); R(bc, xr, xl, 8);
R( xr, xl, 12); R(bc, xl, xr, 7);
R( xl, xr, 11); R(bc, xr, xl, 6);
R( xr, xl, 10); R(bc, xl, xr, 5);
R( xl, xr, 9); R(bc, xr, xl, 4);
R( xr, xl, 8); R(bc, xl, xr, 3);
R( xl, xr, 7); R(bc, xr, xl, 2);
R( xr, xl, 6);
R( xl, xr, 5); xl ^= bc->p[1];
R( xr, xl, 4); xr ^= bc->p[0];
R( xl, xr, 3);
R( xr, xl, 2);
xl ^= p[1];
xr ^= p[0];
*ret_xl = xr; *ret_xl = xr;
*ret_xr = xl; *ret_xr = xl;
#else
uint32_t xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
for(i=_BLOWFISH_ROUNDS+1; i > 1; i-- ) {
xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= p[1];
xl ^= p[0];
*ret_xl = xl;
*ret_xr = xr;
#endif
} }
#undef F #undef F
#undef R #undef R
#warning should loop on length.
void void
blowfish_encrypt(struct blowfish_ctx *bc, uint32_t length, blowfish_encrypt(struct blowfish_ctx *bc, unsigned length,
uint8_t *outbuf, const uint8_t *inbuf) uint8_t *outbuf, const uint8_t *inbuf)
{ {
uint32_t d1, d2; uint32_t d1, d2;
assert(!bc->status); assert(!bc->status);
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; FOR_BLOCKS(length, outbuf, inbuf, BLOWFISH_BLOCK_SIZE)
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; {
d1 = READ_UINT32(inbuf);
d2 = READ_UINT32(inbuf+ 4);
encrypt( bc, &d1, &d2 ); encrypt( bc, &d1, &d2 );
outbuf[0] = (d1 >> 24) & 0xff;
outbuf[1] = (d1 >> 16) & 0xff; WRITE_UINT32(outbuf, d1);
outbuf[2] = (d1 >> 8) & 0xff; WRITE_UINT32(outbuf + 4, d2);
outbuf[3] = d1 & 0xff; }
outbuf[4] = (d2 >> 24) & 0xff;
outbuf[5] = (d2 >> 16) & 0xff;
outbuf[6] = (d2 >> 8) & 0xff;
outbuf[7] = d2 & 0xff;
} }
...@@ -434,22 +337,21 @@ blowfish_decrypt(struct blowfish_ctx *bc, unsigned length, ...@@ -434,22 +337,21 @@ blowfish_decrypt(struct blowfish_ctx *bc, unsigned length,
assert(!bc->status); assert(!bc->status);
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; FOR_BLOCKS(length, outbuf, inbuf, BLOWFISH_BLOCK_SIZE)
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; {
d1 = READ_UINT32(inbuf);
d2 = READ_UINT32(inbuf+ 4);
decrypt( bc, &d1, &d2 ); decrypt( bc, &d1, &d2 );
outbuf[0] = (d1 >> 24) & 0xff;
outbuf[1] = (d1 >> 16) & 0xff; WRITE_UINT32(outbuf, d1);
outbuf[2] = (d1 >> 8) & 0xff; WRITE_UINT32(outbuf + 4, d2);
outbuf[3] = d1 & 0xff; }
outbuf[4] = (d2 >> 24) & 0xff;
outbuf[5] = (d2 >> 16) & 0xff;
outbuf[6] = (d2 >> 8) & 0xff;
outbuf[7] = d2 & 0xff;
} }
int int
blowfish_set_key(struct blowfish_ctx *ctx, blowfish_set_key(struct blowfish_ctx *ctx,
uint32_t keylen, const uint8_t *key) unsigned keylen, const uint8_t *key)
{ {
int i, j; int i, j;
uint32_t data, datal, datar; uint32_t data, datal, datar;
...@@ -463,74 +365,56 @@ blowfish_set_key(struct blowfish_ctx *ctx, ...@@ -463,74 +365,56 @@ blowfish_set_key(struct blowfish_ctx *ctx,
} }
#endif #endif
for(i=0; i < _BLOWFISH_ROUNDS+2; i++ ) *ctx = initial_ctx;
ctx->p[i] = ps[i];
for(i=0; i < 256; i++ ) {
ctx->s0[i] = ks0[i];
ctx->s1[i] = ks1[i];
ctx->s2[i] = ks2[i];
ctx->s3[i] = ks3[i];
}
for(i=j=0; i < _BLOWFISH_ROUNDS+2; i++ ) { for(i=j=0; i < _BLOWFISH_ROUNDS+2; i++ )
#if BIG_ENDIAN_HOST {
#werror BIG_ENDIAN hack used
((byte*)&data)[0] = key[j];
((byte*)&data)[1] = key[(j+1)%keylen];
((byte*)&data)[2] = key[(j+2)%keylen];
((byte*)&data)[3] = key[(j+3)%keylen];
#elif LITTLE_ENDIAN_HOST
#werror LITTLE_ENDIAN hack used
((byte*)&data)[3] = key[j];
((byte*)&data)[2] = key[(j+1)%keylen];
((byte*)&data)[1] = key[(j+2)%keylen];
((byte*)&data)[0] = key[(j+3)%keylen];
#else
data = key[j] << 24 | key[(j+1) % keylen] <<16 data = key[j] << 24 | key[(j+1) % keylen] <<16
| key[(j+2)%keylen] << 8 | key[(j+3)%keylen]; | key[(j+2)%keylen] << 8 | key[(j+3)%keylen];
#endif
ctx->p[i] ^= data; ctx->p[i] ^= data;
j = (j+4) % keylen; j = (j+4) % keylen;
} }
datal = datar = 0; datal = datar = 0;
for(i=0; i < _BLOWFISH_ROUNDS+2; i += 2 ) { for(i=0; i < _BLOWFISH_ROUNDS+2; i += 2 )
{
encrypt( ctx, &datal, &datar ); encrypt( ctx, &datal, &datar );
ctx->p[i] = datal; ctx->p[i] = datal;
ctx->p[i+1] = datar; ctx->p[i+1] = datar;
} }
for(i=0; i < 256; i += 2 ) { for(i=0; i < 256; i += 2 )
{
encrypt( ctx, &datal, &datar ); encrypt( ctx, &datal, &datar );
ctx->s0[i] = datal; ctx->s[0][i] = datal;
ctx->s0[i+1] = datar; ctx->s[0][i+1] = datar;
} }
for(i=0; i < 256; i += 2 ) { for(i=0; i < 256; i += 2 )
{
encrypt( ctx, &datal, &datar ); encrypt( ctx, &datal, &datar );
ctx->s1[i] = datal; ctx->s[1][i] = datal;
ctx->s1[i+1] = datar; ctx->s[1][i+1] = datar;
} }
for(i=0; i < 256; i += 2 ) { for(i=0; i < 256; i += 2 )
{
encrypt( ctx, &datal, &datar ); encrypt( ctx, &datal, &datar );
ctx->s2[i] = datal; ctx->s[2][i] = datal;
ctx->s2[i+1] = datar; ctx->s[2][i+1] = datar;
} }
for(i=0; i < 256; i += 2 ) { for(i=0; i < 256; i += 2 )
{
encrypt( ctx, &datal, &datar ); encrypt( ctx, &datal, &datar );
ctx->s3[i] = datal; ctx->s[3][i] = datal;
ctx->s3[i+1] = datar; ctx->s[3][i+1] = datar;
} }
ctx->status = BLOWFISH_WEAK_KEY;
/* Check for weak key. A weak key is a key in which a value in */ /* Check for weak key. A weak key is a key in which a value in */
/* the P-array (here c) occurs more than once per table. */ /* the P-array (here c) occurs more than once per table. */
for(i=0; i < 255; i++ ) { for(i=0; i < 255; i++ )
for( j=i+1; j < 256; j++) { for( j=i+1; j < 256; j++)
if( (ctx->s0[i] == ctx->s0[j]) || (ctx->s1[i] == ctx->s1[j]) || if( (ctx->s[0][i] == ctx->s[0][j]) || (ctx->s[1][i] == ctx->s[1][j]) ||
(ctx->s2[i] == ctx->s2[j]) || (ctx->s3[i] == ctx->s3[j]) ) (ctx->s[2][i] == ctx->s[2][j]) || (ctx->s[3][i] == ctx->s[3][j]) )
return 0; return 0;
}
}
ctx->status = BLOWFISH_OK; ctx->status = BLOWFISH_OK;
return 1; return 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment