NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: HMAC-SHA1 CUDA program vygenerovaný ChatGPT ;-)

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Caster
Člen
Avatar
Caster:29.3.2023 16:39

Pro zajímavost posílám HMAC-SHA1 CUDA program C++ pro Visual Studio 2022, který mi vygeneroval ChatGPT, funguje 🙂.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <cuda_runtime.h>

#define SHA1_BLOCK_SIZE 64
#define SHA1_HASH_SIZE 20
#define HMAC_BLOCK_SIZE 128

__device__ void sha1_transform(uint32_t* state, const uint8_t* data);
__device__ void hmac_sha1(const uint8_t* key, size_t key_len, const uint8_t* data, size_t data_len, uint8_t* hmac);

__global__ void hmac_sha1_kernel(const uint8_t* key, size_t key_len, const uint8_t* data, size_t data_len, uint8_t* hmac)
{
    __shared__ uint8_t key_block[HMAC_BLOCK_SIZE];
    uint8_t inner_hash[SHA1_HASH_SIZE];
    uint8_t outer_hash[SHA1_HASH_SIZE];
    int i;

    // pad key
    if (threadIdx.x == 0)
    {
        if (key_len <= HMAC_BLOCK_SIZE)
        {
            memcpy(key_block, key, key_len);
            memset(key_block + key_len, 0, HMAC_BLOCK_SIZE - key_len);
        }
        else
        {
            sha1_transform((uint32_t*)key_block, key);
            memset(key_block + SHA1_HASH_SIZE, 0, HMAC_BLOCK_SIZE - SHA1_HASH_SIZE);
        }

        for (i = 0; i < HMAC_BLOCK_SIZE; i++)
        {
            key_block[i] ^= 0x36;
        }
    }

    __syncthreads();

    // compute inner hash
    sha1_transform((uint32_t*)inner_hash, key_block);
    for (i = threadIdx.x; i < data_len; i += blockDim.x)
    {
        key_block[i + SHA1_BLOCK_SIZE] = data[i];
    }

    __syncthreads();

    sha1_transform((uint32_t*)inner_hash, key_block + SHA1_BLOCK_SIZE);
    for (i = threadIdx.x; i < SHA1_HASH_SIZE; i += blockDim.x)
    {
        outer_hash[i] = inner_hash[i] ^ 0x5C;
        key_block[i] = inner_hash[i] ^ 0x36;
    }

    __syncthreads();

    // compute outer hash
    sha1_transform((uint32_t*)outer_hash, key_block);
    for (i = threadIdx.x; i < SHA1_HASH_SIZE; i += blockDim.x)
    {
        hmac[i] = outer_hash[i];
    }

    __syncthreads();

    for (i = threadIdx.x; i < data_len; i += blockDim.x)
    {
        key_block[i + SHA1_BLOCK_SIZE] = hmac[i];
    }

    __syncthreads();

    sha1_transform((uint32_t*)hmac, key_block + SHA1_BLOCK_SIZE);
    for (i = threadIdx.x; i < SHA1_HASH_SIZE; i += blockDim.x)
    {
        hmac[i] = outer_hash[i];
    }

    __syncthreads();
}

__device__ void sha1_transform(uint32_t* state, const uint8_t* data)
{
    uint32_t a, b, c, d, e, f, k, temp;
    uint32_t w[80];

    // load data into message schedule
    for (int i = 0; i < 16; i++)
    {
        w[i] = ((uint32_t)data[i * 4] << 24) | ((uint32_t)data[i * 4 + 1] << 16
            ) | ((uint32_t)data[i * 4 + 2] << 8) | ((uint32_t)data[i * 4 + 3]);
    }

    for (int i = 16; i < 80; i++)
    {
        w[i] = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
        w[i] = (w[i] << 1) | (w[i] >> 31);
    }

    // initialize hash value for this chunk
    a = state[0];
    b = state[1];
    c = state[2];
    d = state[3];
    e = state[4];

    // main loop
    for (int i = 0; i < 80; i++)
    {
        if (i < 20)
        {
            f = (b & c) | ((~b) & d);
            k = 0x5A827999;
        }
        else if (i < 40)
        {
            f = b ^ c ^ d;
            k = 0x6ED9EBA1;
        }
        else if (i < 60)
        {
            f = (b & c) | (b & d) | (c & d);
            k = 0x8F1BBCDC;
        }
        else
        {
            f = b ^ c ^ d;
            k = 0xCA62C1D6;
        }

        temp = ((a << 5) | (a >> 27)) + f + e + k + w[i];
        e = d;
        d = c;
        c = (b << 30) | (b >> 2);
        b = a;
        a = temp;
    }

    // add this chunk's hash to result so far
    state[0] += a;
    state[1] += b;
    state[2] += c;
    state[3] += d;
    state[4] += e;
}

__device__ void hmac_sha1(const uint8_t* key, size_t key_len, const uint8_t* data, size_t data_len, uint8_t* hmac)
{
    sha1_transform((uint32_t*)hmac, key);
    for (int i = 0; i < SHA1_HASH_SIZE; i++)
    {
        hmac[i] ^= 0x5C;
    }
    sha1_transform((uint32_t*)hmac, data);
}

int main()
{
    // Input message and key
    const char* message = "Hello, world!";
    const char* key = "secretkey";
    // Allocate memory on GPU
    size_t message_len = strlen(message);
    size_t key_len = strlen(key);
    uint8_t* d_message, * d_key, * d_hmac;
    cudaMalloc(&d_message, message_len);
    cudaMalloc(&d_key, key_len);
    cudaMalloc(&d_hmac, SHA1_HASH_SIZE);

    // Copy input data to GPU memory
    cudaMemcpy(d_message, message, message_len, cudaMemcpyHostToDevice);
    cudaMemcpy(d_key, key, key_len, cudaMemcpyHostToDevice);

    // Launch kernel
    hmac_sha1_kernel << <1, 128 >> > (d_key, key_len, d_message, message_len, d_hmac);

    // Copy result from GPU memory
    uint8_t hmac[SHA1_HASH_SIZE];
    cudaMemcpy(hmac, d_hmac, SHA1_HASH_SIZE, cudaMemcpyDeviceToHost);

    // Print result
    printf("HMAC-SHA1: ");
    for (int i = 0; i < SHA1_HASH_SIZE; i++)
    {
        printf("%02x", hmac[i]);
    }
    printf("\n");
    // Free memory on GPU
    cudaFree(d_message);
    cudaFree(d_key);
    cudaFree(d_hmac);

    return 0;
}

Zkusil jsem: Viz výše

Chci docílit: Viz výše

 
Odpovědět
29.3.2023 16:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 1 zpráv z 1.