/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give.***************************************************************************** This file contains code to implement a pseudo-random number** generator (PRNG) for SQLite.**** Random numbers are used by some of the database backends in order** to generate random integer keys for tables or random filenames.*/#include "sqliteInt.h"/* All threads share a single random number generator.** This structure is the current state of the generator.*/static SQLITE_WSD struct sqlite3PrngType {u32 s[16]; /* 64 bytes of chacha20 state */u8 out[64]; /* Output bytes */u8 n; /* Output bytes remaining */} sqlite3Prng;/* The RFC-7539 ChaCha20 block function*/#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b))))#define QR(a, b, c, d) ( \a += b, d ^= a, d = ROTL(d,16), \c += d, b ^= c, b = ROTL(b,12), \a += b, d ^= a, d = ROTL(d, 8), \c += d, b ^= c, b = ROTL(b, 7))static void chacha_block(u32 *out, const u32 *in){int i;u32 x[16];memcpy(x, in, 64);for(i=0; i<10; i++){QR(x[0], x[4], x[ 8], x[12]);QR(x[1], x[5], x[ 9], x[13]);QR(x[2], x[6], x[10], x[14]);QR(x[3], x[7], x[11], x[15]);QR(x[0], x[5], x[10], x[15]);QR(x[1], x[6], x[11], x[12]);QR(x[2], x[7], x[ 8], x[13]);QR(x[3], x[4], x[ 9], x[14]);}for(i=0; i<16; i++) out[i] = x[i]+in[i];}/*** Return N random bytes.*/void sqlite3_randomness(int N, void *pBuf){unsigned char *zBuf = pBuf;/* The "wsdPrng" macro will resolve to the pseudo-random number generator** state vector. If writable static data is unsupported on the target,** we have to locate the state vector at run-time. In the more common** case where writable static data is supported, wsdPrng can refer directly** to the "sqlite3Prng" state vector declared above.*/#ifdef SQLITE_OMIT_WSDstruct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);# define wsdPrng p[0]#else# define wsdPrng sqlite3Prng#endif#if SQLITE_THREADSAFEsqlite3_mutex *mutex;#endif#ifndef SQLITE_OMIT_AUTOINITif( sqlite3_initialize() ) return;#endif#if SQLITE_THREADSAFEmutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);#endifsqlite3_mutex_enter(mutex);if( N<=0 || pBuf==0 ){wsdPrng.s[0] = 0;sqlite3_mutex_leave(mutex);return;}/* Initialize the state of the random number generator once,** the first time this routine is called.*/if( wsdPrng.s[0]==0 ){sqlite3_vfs *pVfs = sqlite3_vfs_find(0);static const u32 chacha20_init[] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};memcpy(&wsdPrng.s[0], chacha20_init, 16);if( NEVER(pVfs==0) ){memset(&wsdPrng.s[4], 0, 44);}else{sqlite3OsRandomness(pVfs, 44, (char*)&wsdPrng.s[4]);}wsdPrng.s[15] = wsdPrng.s[12];wsdPrng.s[12] = 0;wsdPrng.n = 0;}assert( N>0 );while( 1 /* exit by break */ ){if( N<=wsdPrng.n ){memcpy(zBuf, &wsdPrng.out[wsdPrng.n-N], N);wsdPrng.n -= N;break;}if( wsdPrng.n>0 ){memcpy(zBuf, wsdPrng.out, wsdPrng.n);N -= wsdPrng.n;zBuf += wsdPrng.n;}wsdPrng.s[12]++;chacha_block((u32*)wsdPrng.out, wsdPrng.s);wsdPrng.n = 64;}sqlite3_mutex_leave(mutex);}#ifndef SQLITE_UNTESTABLE/*** For testing purposes, we sometimes want to preserve the state of** PRNG and restore the PRNG to its saved state at a later time, or** to reset the PRNG to its initial state. These routines accomplish** those tasks.**** The sqlite3_test_control() interface calls these routines to** control the PRNG.*/static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng;void sqlite3PrngSaveState(void){memcpy(&GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),&GLOBAL(struct sqlite3PrngType, sqlite3Prng),sizeof(sqlite3Prng));}void sqlite3PrngRestoreState(void){memcpy(&GLOBAL(struct sqlite3PrngType, sqlite3Prng),&GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),sizeof(sqlite3Prng));}#endif /* SQLITE_UNTESTABLE */
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。