<commit_before>USING: accessors alien.c-types alien.data byte-arrays
combinators.short-circuit continuations destructors init kernel
locals namespaces random windows.advapi32 windows.errors
windows.kernel32 math.bitwise ;
IN: random.windows

TUPLE: windows-rng provider type ;
C: <windows-rng> windows-rng

TUPLE: windows-crypto-context handle ;
C: <windows-crypto-context> windows-crypto-context

M: windows-crypto-context dispose ( tuple -- )
    handle>> 0 CryptReleaseContext win32-error=0/f ;

CONSTANT: factor-crypto-container "FactorCryptoContainer"

:: (acquire-crypto-context) ( provider type flags -- handle ret )
    "HCRYPTPROV" <c-object> :> handle
    handle
    factor-crypto-container
    provider
    type
    flags
    CryptAcquireContextW handle swap ;

: acquire-crypto-context ( provider type -- handle )
    CRYPT_MACHINE_KEYSET
    (acquire-crypto-context)
    0 = [
        GetLastError NTE_BAD_KEYSET =
        [ drop f ] [ win32-error-string throw ] if
    ] [
        *void*
    ] if ;

: create-crypto-context ( provider type -- handle )
    { CRYPT_MACHINE_KEYSET CRYPT_NEWKEYSET } flags
    (acquire-crypto-context) win32-error=0/f *void* ;

ERROR: acquire-crypto-context-failed provider type ;

: attempt-crypto-context ( provider type -- handle )
    {
        [ acquire-crypto-context ] 
        [ create-crypto-context ] 
        [ acquire-crypto-context-failed ]
    } 2|| ;

: windows-crypto-context ( provider type -- context )
    attempt-crypto-context <windows-crypto-context> ;

M: windows-rng random-bytes* ( n tuple -- bytes )
    [
        [ provider>> ] [ type>> ] bi
        windows-crypto-context &dispose
        handle>> swap dup <byte-array>
        [ CryptGenRandom win32-error=0/f ] keep
    ] with-destructors ;

[
    MS_DEF_PROV
    PROV_RSA_FULL <windows-rng> system-random-generator set-global

    [ MS_STRONG_PROV PROV_RSA_FULL <windows-rng> ]
    [ drop MS_ENH_RSA_AES_PROV PROV_RSA_AES <windows-rng> ] recover
    secure-random-generator set-global
] "random.windows" add-startup-hook

[
    [
        system-random-generator get-global &dispose drop
        secure-random-generator get-global &dispose drop
    ] with-destructors
] "random.windows" add-shutdown-hook<commit_msg>don't clean up windows rng yet, needs refactoring first<commit_after>USING: accessors alien.c-types alien.data byte-arrays
combinators.short-circuit continuations destructors init kernel
locals namespaces random windows.advapi32 windows.errors
windows.kernel32 math.bitwise ;
IN: random.windows

TUPLE: windows-rng < disposable provider type ;
C: <windows-rng> windows-rng

TUPLE: windows-crypto-context handle ;
C: <windows-crypto-context> windows-crypto-context

M: windows-crypto-context dispose ( tuple -- )
    handle>> 0 CryptReleaseContext win32-error=0/f ;

CONSTANT: factor-crypto-container "FactorCryptoContainer"

:: (acquire-crypto-context) ( provider type flags -- handle ret )
    "HCRYPTPROV" <c-object> :> handle
    handle
    factor-crypto-container
    provider
    type
    flags
    CryptAcquireContextW handle swap ;

: acquire-crypto-context ( provider type -- handle )
    CRYPT_MACHINE_KEYSET
    (acquire-crypto-context)
    0 = [
        GetLastError NTE_BAD_KEYSET =
        [ drop f ] [ win32-error-string throw ] if
    ] [
        *void*
    ] if ;

: create-crypto-context ( provider type -- handle )
    { CRYPT_MACHINE_KEYSET CRYPT_NEWKEYSET } flags
    (acquire-crypto-context) win32-error=0/f *void* ;

ERROR: acquire-crypto-context-failed provider type ;

: attempt-crypto-context ( provider type -- handle )
    {
        [ acquire-crypto-context ] 
        [ create-crypto-context ] 
        [ acquire-crypto-context-failed ]
    } 2|| ;

: windows-crypto-context ( provider type -- context )
    attempt-crypto-context <windows-crypto-context> ;

M: windows-rng random-bytes* ( n tuple -- bytes )
    [
        [ provider>> ] [ type>> ] bi
        windows-crypto-context &dispose
        handle>> swap dup <byte-array>
        [ CryptGenRandom win32-error=0/f ] keep
    ] with-destructors ;

[
    MS_DEF_PROV
    PROV_RSA_FULL <windows-rng> system-random-generator set-global

    [ MS_STRONG_PROV PROV_RSA_FULL <windows-rng> ]
    [ drop MS_ENH_RSA_AES_PROV PROV_RSA_AES <windows-rng> ] recover
    secure-random-generator set-global
] "random.windows" add-startup-hook

[
    [
        ! system-random-generator get-global &dispose drop
        ! secure-random-generator get-global &dispose drop
    ] with-destructors
] "random.windows" add-shutdown-hook
{'fraction_non_alphanumeric': 0.10685172945582727, 'fraction_numerical': 0.007931262392597489, 'mean_word_length': 3.071748878923767, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6700826', 'n_tokens_mistral': 1492, 'n_tokens_neox': 1433, 'n_words': 310}