mbedtls学习(5)伪随机数生成器

随机数生成器

真随机数生成器(TRNG)一般来自物理设备,伪随机数生成器(PRNG)可以分为”种子“(又称熵源)和内部结构2部分,实际应用中常用真随机数作为种子,再通过伪随机数生成指定长度序列。

CTR_DRBG

伪随机数生成器也称为确定性随机生成器(DRBG),一种近似随机数序列的算法。具体方法有Hash_DRBG、HMAC_DRBG、CTR_DRBG、Hash_DRBG使用单项散列算法作为随机数生成器基础算法、HMAC_DRBG使用消息认证码算法作为随机数生成器基础算法、CTR_DRBG使用分组密码算法的计数器模式作为随机数生成器基础算法

CTR_DRBG例子

需要开启如下宏

#define MBEDTLS_AES_C              使能AES算法
#define MBEDTLS_SHA256_C           使能SHA256算法  
#define MBEDTLS_ENTROPY_C          使能熵源模块
#define MBEDTLS_CTR_DRBG_C         使能随机数模块
#define MBEDTLS_AES_ROM_TABLES     使能预定义S盒
#include 
#include 
#include 

#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform.h"

#define assert_exit(cond, ret) \
    do { if (!(cond)) { \
        printf("  !. assert: failed [line: %d, error: -0x%04X]\n", __LINE__, -ret); \
        goto cleanup; \
    } } while (0)

static void dump_buf(char *info, uint8_t *buf, uint32_t len)
{
    mbedtls_printf("%s", info);
    for (int i = 0; i < len; i++) {
        mbedtls_printf("%s%02X%s", i % 16 == 0 ? "\n     ":" ", 
                        buf[i], i == len - 1 ? "\n":"");
    }
}
/*
static int entropy_source(void *data, uint8_t *output, size_t len, size_t *olen)
{
    uint32_t seed;

    seed = sys_rand32_get();
    if (len > sizeof(seed)) {
        len = sizeof(seed);
    }
    memcpy(output, &seed, len);

    *olen = len;
    return 0;
}*/

int main(void)
{
    int ret = 0;
    uint8_t random[64];
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    const uint8_t *pers = "CTR_DRBG";  
     
    mbedtls_entropy_init(&entropy);//初始化熵结构体
    mbedtls_ctr_drbg_init(&ctr_drbg);//初始化随机数结构体

   /* mbedtls_entropy_add_source(&entropy, entropy_source, NULL,
                               MBEDTLS_ENTROPY_MAX_GATHER,//熵源可用阈值,随机数达到阈值时熵源才被使用
                               MBEDTLS_ENTROPY_SOURCE_STRONG);//强熵源,一般是硬件真随机数生成器
                               //添加熵源接口,设置熵源属性*/
    ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 
                                (const unsigned char *) pers, strlen(pers));//根据个性化字符串跟新种子
    assert_exit(ret == 0, ret);
    mbedtls_printf("\n  . setup rng ... ok\n");

    ret = mbedtls_ctr_drbg_random(&ctr_drbg, random, sizeof(random));//生成指定长度随机数,随机数长度小于MBEDTLS_CTR_DRBG_MAX_REQUEST,默认1024
    assert_exit(ret == 0, ret);
    dump_buf("\n  . generate 64 byte random data ... ok", random, sizeof(random));

cleanup:
    mbedtls_ctr_drbg_free(&ctr_drbg);//释放随机数结构体
    mbedtls_entropy_free(&entropy);//释放熵结构体

    return 0;
}

运行结果
mbedtls学习(5)伪随机数生成器_第1张图片

大素数生成例子

注意打开以下宏

#define MBEDTLS_AES_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_BIGNUM_C           使能大数计算
#define MBEDTLS_GENPRIME           使能素数生成
#define MBEDTLS_AES_ROM_TABLES
#include 
#include 
#include 

#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/bignum.h"
#include "mbedtls/platform.h"

#define assert_exit(cond, ret) \
    do { if (!(cond)) { \
        printf("  !. assert: failed [line: %d, error: -0x%04X]\n", __LINE__, -ret); \
        goto cleanup; \
    } } while (0)

static void dump_buf(char *info, uint8_t *buf, uint32_t len)
{
    mbedtls_printf("%s", info);
    for (int i = 0; i < len; i++) {
        mbedtls_printf("%s%02X%s", i % 16 == 0 ? "\n     ":" ", 
                        buf[i], i == len - 1 ? "\n":"");
    }
}
/*
static int entropy_source(void *data, uint8_t *output, size_t len, size_t *olen)
{
    uint32_t seed;

    seed = sys_rand32_get();
    if(len > sizeof(seed)) {
        len = sizeof(seed);
    }
    memcpy(output, &seed, len);

    *olen = len;
    return 0;
}*/

int main(void)
{
    int ret = 0;
    uint8_t prime[64];
    mbedtls_mpi P, Q;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    const uint8_t *pers = "CTR_DRBG";
  
    mbedtls_mpi_init(&P); //初始化大数结构体
    mbedtls_mpi_init(&Q); //初始化大数结构体
    mbedtls_entropy_init(&entropy);//初始化熵结构体
    mbedtls_ctr_drbg_init(&ctr_drbg);//初始化随机数结构体

   /* mbedtls_entropy_add_source(&entropy, entropy_source, NULL,
                               MBEDTLS_ENTROPY_MAX_GATHER,
                               MBEDTLS_ENTROPY_SOURCE_STRONG);*/
		  //根据个性化字符串更新种子
    ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 
                                (const unsigned char *) pers, strlen(pers));
    assert_exit(ret == 0, ret);
    mbedtls_printf("\n  . setup rng ... ok\n");

    mbedtls_printf("\n  ! Generating large primes may take minutes!\n");  
	//生成大素数,可以指定生成长度
    ret = mbedtls_mpi_gen_prime(&P, sizeof(prime)*8, //生成素数长度
    1, //生成素数标志为1时(P-1)/2也为素数
                                mbedtls_ctr_drbg_random, //随机数生成接口
                                &ctr_drbg);//随机数结构体
    assert_exit(ret == 0, ret);
    //大整数减操作
    ret = mbedtls_mpi_sub_int(&Q, &P, 1);//Q=P-1
    assert_exit(ret == 0, ret);
	//大整数除操作
    ret = mbedtls_mpi_div_int(&Q, NULL, &Q, 2);//Q=Q/2
    assert_exit(ret == 0, ret);
	//判断Q是否为素数
    ret = mbedtls_mpi_is_prime(&Q, mbedtls_ctr_drbg_random, &ctr_drbg);
    assert_exit(ret == 0, ret);
    mbedtls_printf("\n  . Verifying that Q = (P-1)/2 is prime ... ok\n");
	//将大整数写如数组
    mbedtls_mpi_write_binary(&P, prime, sizeof(prime));
    dump_buf("\n  . generate 512 bit prime data ... ok", prime, sizeof(prime));

cleanup:
    mbedtls_mpi_free(&P); //释放大数结构体
    mbedtls_mpi_free(&Q);
    mbedtls_entropy_free(&entropy);
    mbedtls_ctr_drbg_free(&ctr_drbg);

    return 0;
}

运行结构
mbedtls学习(5)伪随机数生成器_第2张图片

你可能感兴趣的:(mbedtls)