static void blake_large_compress(uint64_t *v,const void *m){ uint8_t r,i; uint8_t a,b,c,d, s0, s1, sigma_idx=0; for(r=0; r<16; ++r){ for(i=0; i<8; ++i){ a = pgm_read_byte(blake_index_lut+4*i+0); b = pgm_read_byte(blake_index_lut+4*i+1); c = pgm_read_byte(blake_index_lut+4*i+2); d = pgm_read_byte(blake_index_lut+4*i+3); s0 = pgm_read_byte(blake_sigma+sigma_idx); s1 = s0&0x0f; s0 >>= 4; ++sigma_idx; if(sigma_idx>=80){ sigma_idx-=80; } v[a] += v[b] + (((uint64_t*)m)[s0] ^ pgm_read_qword(&(blake_c[s1]))); v[d] = ROTR64(v[d]^v[a], 32); v[c] += v[d]; v[b] = ROTR64(v[b]^v[c], 25); v[a] += v[b] + (((uint64_t*)m)[s1] ^ pgm_read_qword(&(blake_c[s0]))); v[d] = ROTR64(v[d]^v[a], 16); v[c] += v[d]; v[b] = ROTR64(v[b]^v[c], 11); } } }
void speck128_encryptx( const void *key, void *in) { uint64_t i, t, k0, k1, k2, k3, x0, x1; // copy 256-bit key to local space k0 = ((uint64_t*)key)[0]; k1 = ((uint64_t*)key)[1]; k2 = ((uint64_t*)key)[2]; k3 = ((uint64_t*)key)[3]; // copy input to local space x0 = ((uint64_t*)in)[0]; x1 = ((uint64_t*)in)[1]; for (i=0; i<34; i++) { // encrypt block x1 = (ROTR64(x1, 8) + x0) ^ k0; x0 = ROTL64(x0, 3) ^ x1; // create next subkey k1 = (ROTR64(k1, 8) + k0) ^ i; k0 = ROTL64(k0, 3) ^ k1; XCHG(k3, k2, t); XCHG(k3, k1, t); } // save result ((uint64_t*)in)[0] = x0; ((uint64_t*)in)[1] = x1; }
void speck128_encrypt( int enc, void *in, const void *keys) { uint64_t i; uint64_t *ks=(uint64_t*)keys; // copy input to local space uint64_t x = ((uint64_t*)in)[0]; uint64_t y = ((uint64_t*)in)[1]; for (i=0; i<34; i++) { if (enc == SPECK_DECRYPT) { x = ROTR64(x ^ y, 3); y = ROTL64((y ^ ks[34-1-i]) - x, 8); } else { y = (ROTR64(y, 8) + x) ^ ks[i]; x = ROTL64(x, 3) ^ y; } } // save result ((uint64_t*)in)[0] = x; ((uint64_t*)in)[1] = y; }
static void blake_large_compress(uint64_t* v,const void* m) { uint8_t r,i; uint16_t s, *p=(uint16_t*)blake_sigma; union { uint32_t v32; uint8_t v8[4]; } idx; for(r=0; r<16; ++r) { for(i=0; i<8; ++i) { idx.v32 = ((uint32_t*)blake_index_lut)[i]; s = *p++; if(p==(uint16_t*)(blake_sigma + 160)) { p=(uint16_t*)blake_sigma; } A += B + (((uint64_t*)m)[s&0xff] ^ blake_c[s>>8]); D = ROTR64(D^A, 32); C += D; B = ROTR64(B^C, 25); A += B + (((uint64_t*)m)[s>>8] ^ blake_c[s&0xff]); D = ROTR64(D^A, 16); C += D; B = ROTR64(B^C, 11); } } }
void speck128_setkey( const void *in, void *out) { uint64_t i, t, k0, k1, k2, k3; // copy 256-bit key to local space k0 = ((uint64_t*)in)[0]; k1 = ((uint64_t*)in)[1]; k2 = ((uint64_t*)in)[2]; k3 = ((uint64_t*)in)[3]; // expand 256-bit key into round keys for (i=0; i<34; i++) { ((uint64_t*)out)[i] = k0; k1 = (ROTR64(k1, 8) + k0) ^ i; k0 = ROTL64(k0, 3) ^ k1; // rotate left 64-bits XCHG(k3, k2, t); XCHG(k3, k1, t); } }
void siphash24x(void *out, void const *in, int inlen, void const *key) { uint64_t v[4]; uint64_t k0, k1, x, b=inlen; int c, r, i, len=inlen; uint8_t *p=(uint8_t*)in; b <<= 56; k0 = ((uint64_t*)key)[0]; k1 = ((uint64_t*)key)[1]; v[0] = k0 ^ 0x736F6D6570736575ULL; v[1] = k1 ^ 0x646F72616E646F6DULL; v[2] = k0 ^ 0x6C7967656E657261ULL; v[3] = k1 ^ 0x7465646279746573ULL; // process all bytes while (len >= 0) { // get 8 or whatever bytes remaining. x = 0; r = (len < 8) ? len : 8; if (len != 0) { for (i=0; i<r; i++) { x |= *p++; x = ROTR64(x, 8); } } // subtract r from len len -= r; // if this is last block if (len<=0) { // if r is less than 8 if (r<8) { x = ROTL64(x, (r << 3)); x |= b; } else { perm(0, x, v); x=b; } } // permutate perm(0, x, v); } // do last permutation perm(1, x, v); ((uint64_t*)out)[0] = v[0] ^ v[1] ^ v[2] ^ v[3]; }