/* * Salsa20/8 Core function (combined with XOR) * * This function accepts two 64-byte Python byte strings (x and y). * It creates a new 64-byte Python byte string with the result * of the expression salsa20_8(xor(x,y)). */ EXPORT_SYM int Salsa20_8_core(const uint8_t *x, const uint8_t *y, uint8_t *out) { uint32_t input_32[16]; int i; if (NULL==x || NULL==y || NULL==out) return ERR_NULL; for (i=0; i<16; i++) { uint32_t tmp; tmp = LOAD_U32_LITTLE(&x[i*4]); input_32[i] = LOAD_U32_LITTLE(&y[i*4]); input_32[i] ^= tmp; } _salsa20_block(8, input_32, out); return 0; }
EXPORT_SYM int Salsa20_stream_init(uint8_t *key, size_t keylen, uint8_t *nonce, size_t nonce_len, stream_state **pSalsaState) { const uint8_t *constants; uint32_t *input; stream_state *salsaState; unsigned i; if (NULL == pSalsaState || NULL == key || NULL == nonce) return ERR_NULL; if (keylen != 16 && keylen != 32) return ERR_KEY_SIZE; constants = keylen == 32 ? sigma : tau; if (nonce_len != 8) return ERR_NONCE_SIZE; *pSalsaState = salsaState = calloc(1, sizeof(stream_state)); if (NULL == salsaState) return ERR_MEMORY; input = salsaState->input; input[0] = LOAD_U32_LITTLE(constants + 0); /** Set input[1..4] **/ for (i=0; i<4; i++) input[i+1] = LOAD_U32_LITTLE(key + 4*i); input[5] = LOAD_U32_LITTLE(constants + 4); input[6] = LOAD_U32_LITTLE(nonce + 0); input[7] = LOAD_U32_LITTLE(nonce + 4); /* Block counter setup*/ input[8] = 0; input[9] = 0; input[10] = LOAD_U32_LITTLE(constants + 8); /** Set input[11..14] **/ if (keylen == 32) { key += 16; } for (i=0; i<4; i++) input[i+11] = LOAD_U32_LITTLE(key + 4*i); input[15] = LOAD_U32_LITTLE(constants + 12); salsaState->blockindex = 64; return 0; }
/* The RIPEMD160 compression function. Operates on self->buf */ static void ripemd160_compress(hash_state *self) { unsigned w, round; uint32_t T; uint32_t AL, BL, CL, DL, EL; /* left line */ uint32_t AR, BR, CR, DR, ER; /* right line */ uint32_t bufw[16]; for (w=0; w<16; w++) bufw[w] = LOAD_U32_LITTLE(&self->buf[w*4]); /* Load the left and right lines with the initial state */ AL = AR = self->h[0]; BL = BR = self->h[1]; CL = CR = self->h[2]; DL = DR = self->h[3]; EL = ER = self->h[4]; /* Round 1 */ round = 0; for (w = 0; w < 16; w++) { /* left line */ T = ROL(SL[round][w], AL + F1(BL, CL, DL) + bufw[RL[round][w]] + KL[round]) + EL; AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T; } for (w = 0; w < 16; w++) { /* right line */ T = ROL(SR[round][w], AR + F5(BR, CR, DR) + bufw[RR[round][w]] + KR[round]) + ER; AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T; } /* Round 2 */ round++; for (w = 0; w < 16; w++) { /* left line */ T = ROL(SL[round][w], AL + F2(BL, CL, DL) + bufw[RL[round][w]] + KL[round]) + EL; AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T; } for (w = 0; w < 16; w++) { /* right line */ T = ROL(SR[round][w], AR + F4(BR, CR, DR) + bufw[RR[round][w]] + KR[round]) + ER; AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T; } /* Round 3 */ round++; for (w = 0; w < 16; w++) { /* left line */ T = ROL(SL[round][w], AL + F3(BL, CL, DL) + bufw[RL[round][w]] + KL[round]) + EL; AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T; } for (w = 0; w < 16; w++) { /* right line */ T = ROL(SR[round][w], AR + F3(BR, CR, DR) + bufw[RR[round][w]] + KR[round]) + ER; AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T; } /* Round 4 */ round++; for (w = 0; w < 16; w++) { /* left line */ T = ROL(SL[round][w], AL + F4(BL, CL, DL) + bufw[RL[round][w]] + KL[round]) + EL; AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T; } for (w = 0; w < 16; w++) { /* right line */ T = ROL(SR[round][w], AR + F2(BR, CR, DR) + bufw[RR[round][w]] + KR[round]) + ER; AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T; } /* Round 5 */ round++; for (w = 0; w < 16; w++) { /* left line */ T = ROL(SL[round][w], AL + F5(BL, CL, DL) + bufw[RL[round][w]] + KL[round]) + EL; AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T; } for (w = 0; w < 16; w++) { /* right line */ T = ROL(SR[round][w], AR + F1(BR, CR, DR) + bufw[RR[round][w]] + KR[round]) + ER; AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T; } /* Final mixing stage */ T = self->h[1] + CL + DR; self->h[1] = self->h[2] + DL + ER; self->h[2] = self->h[3] + EL + AR; self->h[3] = self->h[4] + AL + BR; self->h[4] = self->h[0] + BL + CR; self->h[0] = T; /* Clear the buffer and wipe the temporary variables */ T = AL = BL = CL = DL = EL = AR = BR = CR = DR = ER = 0; memset(&self->buf, 0, sizeof(self->buf)); self->bufpos = 0; }
EXPORT_SYM int md4_update(hash_state *hs, const uint8_t *buf, size_t len) { if (NULL == hs || NULL == buf) { return ERR_NULL; } assert(hs->count < 64); hs->bitlen += (uint64_t)len * 8; while (len>0) { unsigned left, tc; left = 64 - hs->count; tc = (unsigned)MIN(left, len); memcpy(hs->buf+hs->count, buf, tc); hs->count += tc; buf += tc; len -= tc; if (hs->count==64) { uint32_t X[16], A, B, C, D; unsigned j; hs->count=0; for(j=0; j<16; j++) { X[j] = LOAD_U32_LITTLE(&hs->buf[j*4]); } A=hs->A; B=hs->B; C=hs->C; D=hs->D; #define function(a,b,c,d,k,s) a=ROL(a+F(b,c,d)+X[k],s); function(A,B,C,D, 0, 3); function(D,A,B,C, 1, 7); function(C,D,A,B, 2,11); function(B,C,D,A, 3,19); function(A,B,C,D, 4, 3); function(D,A,B,C, 5, 7); function(C,D,A,B, 6,11); function(B,C,D,A, 7,19); function(A,B,C,D, 8, 3); function(D,A,B,C, 9, 7); function(C,D,A,B,10,11); function(B,C,D,A,11,19); function(A,B,C,D,12, 3); function(D,A,B,C,13, 7); function(C,D,A,B,14,11); function(B,C,D,A,15,19); #undef function #define function(a,b,c,d,k,s) a=ROL(a+G(b,c,d)+X[k]+(uint32_t)0x5a827999,s); function(A,B,C,D, 0, 3); function(D,A,B,C, 4, 5); function(C,D,A,B, 8, 9); function(B,C,D,A,12,13); function(A,B,C,D, 1, 3); function(D,A,B,C, 5, 5); function(C,D,A,B, 9, 9); function(B,C,D,A,13,13); function(A,B,C,D, 2, 3); function(D,A,B,C, 6, 5); function(C,D,A,B,10, 9); function(B,C,D,A,14,13); function(A,B,C,D, 3, 3); function(D,A,B,C, 7, 5); function(C,D,A,B,11, 9); function(B,C,D,A,15,13); #undef function #define function(a,b,c,d,k,s) a=ROL(a+H(b,c,d)+X[k]+(uint32_t)0x6ed9eba1,s); function(A,B,C,D, 0, 3); function(D,A,B,C, 8, 9); function(C,D,A,B, 4,11); function(B,C,D,A,12,15); function(A,B,C,D, 2, 3); function(D,A,B,C,10, 9); function(C,D,A,B, 6,11); function(B,C,D,A,14,15); function(A,B,C,D, 1, 3); function(D,A,B,C, 9, 9); function(C,D,A,B, 5,11); function(B,C,D,A,13,15); function(A,B,C,D, 3, 3); function(D,A,B,C,11, 9); function(C,D,A,B, 7,11); function(B,C,D,A,15,15); hs->A+=A; hs->B+=B; hs->C+=C; hs->D+=D; } } return 0; }