pike.git
/
src
/
post_modules
/
Nettle
/
nettle.cmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/post_modules/Nettle/nettle.cmod:308:
} else { hash = pike_crypt_md5(pw->len, pw->str, salt->len, salt->str, magic->len, magic->str); } push_text(hash); }
-
-
static const char *crypto_functions[] = {
-
"block_size",
-
"key_size",
-
"set_encrypt_key",
-
"set_decrypt_key",
-
"crypt",
-
0
-
};
-
-
static const char *assert_is_crypto_object(struct program *p,
-
const char *const *required) {
-
while (*required) {
-
if (find_identifier( (char *) *required, p) < 0)
-
return *required;
-
required++;
-
}
-
return 0;
-
}
-
-
static struct object *make_cipher_object(INT32 args) {
-
ptrdiff_t fun;
-
const char *missing;
-
struct svalue *top = Pike_sp-args;
-
struct object *obj;
-
-
switch(TYPEOF(*top))
-
{
-
case T_PROGRAM:
-
obj = clone_object(top->u.program, args-1);
-
break;
-
-
case T_FUNCTION:
-
apply_svalue(Pike_sp - args, args-1);
-
-
/* Check return value */
-
if(TYPEOF(Pike_sp[-1]) != T_OBJECT)
-
Pike_error("Returned value is not an object.\n");
-
-
add_ref(obj = Pike_sp[-1].u.object);
-
break;
-
-
case T_OBJECT:
-
fun = -1;
-
missing = assert_is_crypto_object(top->u.object->prog,
-
crypto_functions);
-
if(missing)
-
fun = FIND_LFUN(top->u.object->prog, LFUN_CALL);
-
if(fun!=-1) {
-
apply_low(top->u.object, fun, args-1);
-
stack_swap();
-
pop_stack();
-
}
-
else
-
if(args!=1) Pike_error("Too many arguments.\n");
-
-
add_ref(obj = top->u.object);
-
break;
-
default:
-
SIMPLE_BAD_ARG_ERROR("create", 1, "program|object|function");
-
}
-
-
pop_stack();
-
-
missing = assert_is_crypto_object(obj->prog, crypto_functions);
-
if(missing) {
-
free_object(obj);
-
Pike_error("Object is missing identifier \"%s\"\n", missing);
-
}
-
-
return obj;
-
}
-
-
-
/*! @class CBC
-
*! Implementation of the cipher block chaining mode (CBC). Works as
-
*! a wrapper for the cipher algorithm put in create.
-
*!
-
*! @note
-
*! Use @[Crypto.CBC] instead.
-
*/
-
PIKECLASS CBC
-
{
-
/*! @decl inherit __builtin.Nettle.Cipher
-
*/
-
INHERIT "__builtin.Nettle.Cipher";
-
-
CVAR struct object *object;
-
CVAR unsigned INT8 *iv;
-
CVAR INT32 block_size;
-
CVAR INT32 mode;
-
-
INIT
-
{
-
THIS->object = NULL;
-
THIS->iv = NULL;
-
THIS->block_size = 0;
-
THIS->mode = 0;
-
}
-
-
EXIT
-
gc_trivial;
-
{
-
if(THIS->object) {
-
free_object(THIS->object);
-
}
-
if(THIS->iv) {
-
guaranteed_memset(THIS->iv, 0, THIS->block_size);
-
free(THIS->iv);
-
}
-
}
-
-
INLINE static void cbc_encrypt_step(const unsigned INT8 *const source,
-
unsigned INT8 *dest)
-
{
-
INT32 block_size = THIS->block_size;
-
INT32 i;
-
-
for(i=0; i < block_size; i++)
-
THIS->iv[i] ^= source[i];
-
-
push_string(make_shared_binary_string((INT8 *)THIS->iv, block_size));
-
safe_apply(THIS->object, "crypt", 1);
-
-
if(TYPEOF(Pike_sp[-1]) != T_STRING)
-
Pike_error("Expected string from crypt()\n");
-
-
if(Pike_sp[-1].u.string->len != block_size) {
-
Pike_error("Bad string length %ld returned from crypt()\n",
-
DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
-
}
-
MEMCPY(THIS->iv, Pike_sp[-1].u.string->str, block_size);
-
MEMCPY(dest, Pike_sp[-1].u.string->str, block_size);
-
pop_stack();
-
}
-
-
INLINE static void cbc_decrypt_step(const unsigned INT8 *const source,
-
unsigned INT8 *dest)
-
{
-
INT32 block_size = THIS->block_size;
-
INT32 i;
-
-
push_string(make_shared_binary_string((const INT8 *)source, block_size));
-
safe_apply(THIS->object, "crypt", 1);
-
-
if(TYPEOF(Pike_sp[-1]) != T_STRING)
-
Pike_error("Expected string from crypt()\n");
-
-
if(Pike_sp[-1].u.string->len != block_size) {
-
Pike_error("Bad string length %ld returned from crypt()\n",
-
DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
-
}
-
-
for(i=0; i < block_size; i++)
-
dest[i] = THIS->iv[i] ^ Pike_sp[-1].u.string->str[i];
-
-
pop_stack();
-
MEMCPY(THIS->iv, source, block_size);
-
}
-
-
/*! @decl void create(program|object|function cipher, mixed ... args)
-
*!
-
*! Initialize the CBC wrapper with a cipher algorithm. If it is a
-
*! program, an object will be instantiated with @[args] as
-
*! arguments. If it is an object that doesn't conform to the cipher
-
*! API, but has an @[LFUN::`()], that LFUN will be called. If it is
-
*! a function, that function will be called with @[args] as
-
*! arguments.
-
*/
-
PIKEFUN void create(program|object|function cipher, mixed ... more)
-
flags ID_PROTECTED;
-
{
-
int old_block_size = THIS->block_size;
-
THIS->object = make_cipher_object(args);
-
-
safe_apply(THIS->object, "block_size", 0);
-
-
if(TYPEOF(Pike_sp[-1]) != T_INT)
-
Pike_error("block_size() didn't return an int.\n");
-
-
THIS->block_size = Pike_sp[-1].u.integer;
-
-
pop_stack();
-
-
if ((!THIS->block_size) ||
-
(THIS->block_size > 4096))
-
Pike_error("Bad block size %d.\n", THIS->block_size);
-
-
if(THIS->iv) {
-
guaranteed_memset(THIS->iv, 0, old_block_size);
-
free(THIS->iv);
-
}
-
THIS->iv = (unsigned INT8 *)xalloc(THIS->block_size);
-
MEMSET(THIS->iv, 0, THIS->block_size);
-
}
-
-
/*! @decl string(0..255) name()
-
*! Returns the string @expr{"CBC(x)"@} where x is the
-
*! encapsulated algorithm.
-
*/
-
PIKEFUN string(0..255) name()
-
optflags OPT_TRY_OPTIMIZE;
-
{
-
push_constant_text("CBC(");
-
safe_apply(THIS->object, "name", 0);
-
push_constant_text(")");
-
f_add(3);
-
}
-
-
/*! @decl int(0..) block_size()
-
*! Reurns the block size of the encapsulated cipher.
-
*/
-
PIKEFUN int(0..) block_size()
-
optflags OPT_TRY_OPTIMIZE;
-
{
-
RETURN THIS->block_size;
-
}
-
-
/*! @decl int(0..) key_size()
-
*! Returns the key size of the encapsulated cipher.
-
*/
-
PIKEFUN int(0..) key_size()
-
optflags OPT_EXTERNAL_DEPEND;
-
{
-
safe_apply(THIS->object, "key_size", args);
-
}
-
-
/*! @decl this_program set_encrypt_key(string key, int|void flags)
-
*!
-
*! Prepare the cipher and the wrapper for encrypting with the given
-
*! @[key]. The @[key] memory will be cleared before released.
-
*/
-
PIKEFUN object set_encrypt_key(string key, int|void flags)
-
optflags OPT_SIDE_EFFECT;
-
{
-
assert(THIS->block_size);
-
THIS->mode = 0;
-
key->flags |= STRING_CLEAR_ON_EXIT;
-
safe_apply(THIS->object, "set_encrypt_key", args);
-
pop_stack();
-
RETURN this_object();
-
}
-
-
/*! @decl this_program set_decrypt_key(string key, int|void flags)
-
*!
-
*! Prepare the cipher and the wrapper for decrypting with the given
-
*! @[key]. The @[key] memory will be cleared before released.
-
*/
-
PIKEFUN object set_decrypt_key(string key, int|void flags)
-
optflags OPT_SIDE_EFFECT;
-
{
-
assert(THIS->block_size);
-
THIS->mode = 1;
-
key->flags |= STRING_CLEAR_ON_EXIT;
-
safe_apply(THIS->object, "set_decrypt_key", args);
-
pop_stack();
-
RETURN this_object();
-
}
-
-
/*! @decl this_program set_iv(string iv)
-
*!
-
*! Set the initialization vector to @[iv]. The @[iv] memory will be
-
*! cleared before released.
-
*/
-
PIKEFUN object set_iv(string iv)
-
optflags OPT_SIDE_EFFECT;
-
{
-
assert(THIS->iv);
-
iv->flags |= STRING_CLEAR_ON_EXIT;
-
NO_WIDE_STRING(iv);
-
if(iv->len != THIS->block_size)
-
Pike_error("Argument incompatible with cipher block size.\n");
-
MEMCPY(THIS->iv, iv->str, THIS->block_size);
-
RETURN this_object();
-
}
-
-
/*! @decl string(0..255) crypt(string data)
-
*!
-
*! Encrypt/decrypt @[data] and return the result. @[data] must
-
*! be an integral number of blocks.
-
*!
-
*! Neither the input or output data is not automatically memory
-
*! scrubbed, unless @[String.secure] has been called on the data.
-
*/
-
PIKEFUN string(0..255) crypt(string data) {
-
unsigned INT8 *result;
-
INT32 offset = 0;
-
ONERROR uwp;
-
-
NO_WIDE_STRING(data);
-
-
if(data->len % THIS->block_size)
-
Pike_error("Data length not multiple of block size.\n");
-
-
if(!(result = malloc(data->len)))
-
SIMPLE_OUT_OF_MEMORY_ERROR("crypt", data->len);
-
SET_ONERROR (uwp, free, result);
-
-
if(THIS->mode == 0) {
-
while (offset < data->len) {
-
cbc_encrypt_step((const unsigned INT8 *)data->str + offset,
-
result + offset);
-
offset += THIS->block_size;
-
}
-
}
-
else {
-
while (offset < data->len) {
-
cbc_decrypt_step((const unsigned INT8 *)data->str + offset,
-
result + offset);
-
offset += THIS->block_size;
-
}
-
}
-
-
pop_n_elems(args);
-
push_string(make_shared_binary_string((INT8 *)result, offset));
-
guaranteed_memset(result, 0, offset);
-
CALL_AND_UNSET_ONERROR (uwp);
-
}
-
}
-
-
/*! @endclass
-
*/
-
-
/*! @class Proxy
-
*! Acts as a buffer so that data can be fed to a cipher in blocks
-
*! that don't correspond to cipher block sizes.
-
*!
-
*! @note
-
*! Use @[Crypto.Buffer] instead.
-
*/
-
PIKECLASS Proxy {
-
/*! @decl inherit __builtin.Nettle.Cipher
-
*/
-
INHERIT "__builtin.Nettle.Cipher";
-
-
CVAR struct object *object;
-
CVAR int block_size;
-
CVAR unsigned char *backlog;
-
CVAR int backlog_len;
-
-
INIT {
-
THIS->object = NULL;
-
THIS->block_size = 0;
-
THIS->backlog = NULL;
-
THIS->backlog_len = 0;
-
}
-
-
EXIT
-
gc_trivial;
-
{
-
if(THIS->backlog) {
-
guaranteed_memset(THIS->backlog, 0, THIS->block_size);
-
free(THIS->backlog);
-
THIS->backlog = NULL;
-
}
-
if(THIS->object) {
-
free_object(THIS->object);
-
THIS->object = NULL;
-
}
-
}
-
-
/*! @decl void create(program|object|function cipher, mixed ... args)
-
*!
-
*! Initialize the Proxy wrapper with a cipher algorithm. If it is a
-
*! program, an object will be instantiated with @[args] as
-
*! arguments. If it is an object that doesn't conform to the cipher
-
*! API, but has an @[LFUN::`()], that LFUN will be called. If it is
-
*! a function, that function will be called with @[args] as
-
*! arguments.
-
*/
-
PIKEFUN void create(program|object|function cipher, mixed ... more)
-
flags ID_PROTECTED;
-
{
-
exit_Proxy_struct();
-
THIS->object = make_cipher_object(args);
-
-
safe_apply(THIS->object, "block_size", 0);
-
if (TYPEOF(Pike_sp[-1]) != T_INT)
-
Pike_error("block_size() didn't return an int\n");
-
THIS->block_size = Pike_sp[-1].u.integer;
-
-
pop_stack();
-
-
if ((!THIS->block_size) ||
-
(THIS->block_size > 4096))
-
Pike_error("Bad block size %ld\n", DO_NOT_WARN((long)THIS->block_size));
-
-
THIS->backlog = (unsigned char *)xalloc(THIS->block_size);
-
THIS->backlog_len = 0;
-
MEMSET(THIS->backlog, 0, THIS->block_size);
-
}
-
-
/*! @decl string(0..255) name()
-
*! Returns the string @expr{"Proxy(x)"@} where x is the
-
*! encapsulated algorithm.
-
*/
-
PIKEFUN string(0..255) name()
-
optflags OPT_TRY_OPTIMIZE;
-
{
-
push_constant_text("Proxy(");
-
safe_apply(THIS->object, "name", 0);
-
push_constant_text(")");
-
f_add(3);
-
}
-
-
/*! @decl int(0..) block_size()
-
*!
-
*! Get the block size of the contained block crypto.
-
*/
-
PIKEFUN int(0..) block_size()
-
optflags OPT_TRY_OPTIMIZE;
-
{
-
RETURN THIS->block_size;
-
}
-
-
/*! @decl int(0..) key_size()
-
*!
-
*! Get the key size of the contained block crypto.
-
*/
-
PIKEFUN int(0..) key_size()
-
optflags OPT_EXTERNAL_DEPEND;
-
{
-
safe_apply(THIS->object, "key_size", args);
-
}
-
-
/*! @decl this_program set_encrypt_key(string key)
-
*!
-
*! Set the encryption key. The @[key] memory will be cleared before
-
*! released.
-
*!
-
*! @note
-
*! As a side-effect any buffered data will be cleared.
-
*/
-
PIKEFUN object set_encrypt_key(string key)
-
optflags OPT_SIDE_EFFECT;
-
{
-
THIS->backlog_len = 0;
-
key->flags |= STRING_CLEAR_ON_EXIT;
-
safe_apply(THIS->object, "set_encrypt_key", args);
-
pop_stack();
-
RETURN this_object();
-
}
-
-
/*! @decl this_program set_decrypt_key(string key)
-
*!
-
*! Set the decryption key. The @[key] memory will be cleared before
-
*! released.
-
*!
-
*! @note
-
*! As a side-effect any buffered data will be cleared.
-
*/
-
PIKEFUN object set_decrypt_key(string key)
-
optflags OPT_SIDE_EFFECT;
-
{
-
THIS->backlog_len = 0;
-
key->flags |= STRING_CLEAR_ON_EXIT;
-
safe_apply(THIS->object, "set_decrypt_key", args);
-
pop_stack();
-
RETURN this_object();
-
}
-
-
/*! @decl string(0..255) crypt(string data)
-
*!
-
*! Encrypt or decrypt some data.
-
*!
-
*! Adds data to be en/decrypted to the buffer. If there's enough
-
*! data to en/decrypt a block, that will be done, and the result
-
*! returned. Any unprocessed data will be left in the buffer.
-
*!
-
*! Neither the input or output data is not automatically memory
-
*! scrubbed, unless @[String.secure] has been called on the data.
-
*/
-
PIKEFUN string(0..255) crypt(string data) {
-
unsigned char *result;
-
ptrdiff_t roffset = 0;
-
ptrdiff_t soffset = 0;
-
ptrdiff_t len;
-
ONERROR uwp;
-
-
if (!(result = malloc(data->len + THIS->block_size)))
-
SIMPLE_OUT_OF_MEMORY_ERROR("crypt", data->len + THIS->block_size);
-
SET_ONERROR (uwp, free, result);
-
-
if (THIS->backlog_len) {
-
if (data->len >= (THIS->block_size - THIS->backlog_len)) {
-
MEMCPY(THIS->backlog + THIS->backlog_len, data->str,
-
(THIS->block_size - THIS->backlog_len));
-
soffset += (THIS->block_size - THIS->backlog_len);
-
THIS->backlog_len = 0;
-
push_string(make_shared_binary_string((char *)THIS->backlog,
-
THIS->block_size));
-
safe_apply(THIS->object, "crypt", 1);
-
if (TYPEOF(Pike_sp[-1]) != T_STRING)
-
Pike_error("crypt() did not return string\n");
-
if (Pike_sp[-1].u.string->len != THIS->block_size)
-
Pike_error("Unexpected string length %ld\n",
-
DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
-
-
MEMCPY(result, Pike_sp[-1].u.string->str, THIS->block_size);
-
roffset = THIS->block_size;
-
pop_stack();
-
} else {
-
MEMCPY(THIS->backlog + THIS->backlog_len,
-
data->str, data->len);
-
THIS->backlog_len += data->len;
-
pop_n_elems(args);
-
push_empty_string();
-
CALL_AND_UNSET_ONERROR (uwp);
-
return;
-
}
-
}
-
-
len = (Pike_sp[-1].u.string->len - soffset);
-
len -= len % THIS->block_size;
-
-
if (len) {
-
push_string(make_shared_binary_string(Pike_sp[-1].u.string->str +
-
soffset, len));
-
soffset += len;
-
-
safe_apply(THIS->object, "crypt", 1);
-
-
if (TYPEOF(Pike_sp[-1]) != T_STRING)
-
Pike_error("crypt() did not return string.\n");
-
if (Pike_sp[-1].u.string->len != len)
-
Pike_error("crypt() Unexpected string length %ld.\n",
-
DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
-
-
MEMCPY(result + roffset, Pike_sp[-1].u.string->str, len);
-
-
pop_stack();
-
}
-
-
if (soffset < Pike_sp[-1].u.string->len) {
-
MEMCPY(THIS->backlog, Pike_sp[-1].u.string->str + soffset,
-
Pike_sp[-1].u.string->len - soffset);
-
THIS->backlog_len = Pike_sp[-1].u.string->len - soffset;
-
}
-
-
pop_n_elems(args);
-
-
push_string(make_shared_binary_string((char *)result, roffset + len));
-
guaranteed_memset(result, 0, roffset + len);
-
CALL_AND_UNSET_ONERROR (uwp);
-
}
-
-
/*! @decl string(0..255) pad(void|int method)
-
*!
-
*! Pad and encrypt any data left in the buffer. The output data is
-
*! not automatically memory scrubbed, unless @[String.secure] is
-
*! called on the data.
-
*!
-
*! @param method
-
*! The type of padding to apply to the buffer.
-
*! @int
-
*! @value Crypto.PAD_ISO_10126
-
*! Pads according to ISO 10126, which means filling all extra
-
*! space with random data and putting the size of the
-
*! non-payload data last.
-
*! @value Crypto.PAD_SSL
-
*! As ISO 10126, but with the size of the random data last.
-
*! @value Crypto.PAD_ANSI_X923
-
*! Pads according to ANSI X.923, which means filling all extra
-
*! space with zero and putting the size of the non-payload data
-
*! last.
-
*! @value Crypto.PAD_PKCS7
-
*! Pads according to PKCS7 / RFC 3852, which means filling all
-
*! extra space with the size of the extra space.
-
*! @value Crypto.PAD_ZERO
-
*! Fills the extra space with null bytes. To correctly remove
-
*! the padding the clear text data must not end with a null
-
*! byte. In that case the data would have to be manually
-
*! padded/unpadded before/after calling @[crypt()].
-
*! @endint
-
*! Defaults to Crypto.PAD_SSL for compatibility reasons.
-
*!
-
*! @seealso
-
*! @[unpad()]
-
*/
-
PIKEFUN string(0..255) pad(void|int method) {
-
ptrdiff_t i;
-
int m = 0;
-
int size = THIS->block_size - THIS->backlog_len;
-
-
if(method)
-
{
-
if(TYPEOF(*method) != PIKE_T_INT)
-
Pike_error("Bad argument type.\n");
-
m = method->u.integer;
-
}
-
-
switch(m)
-
{
-
case 0:
-
size--;
-
break;
-
case 4:
-
if( THIS->backlog_len>0 &&
-
THIS->backlog[THIS->backlog_len-1] == 0 )
-
Pike_error("Using zero padding on a zero terminated string.\n");
-
size = 0;
-
break;
-
}
-
-
for (i = THIS->backlog_len; i < THIS->block_size - 1; i++)
-
switch(m)
-
{
-
default:
-
Pike_error("Unknown method.\n");
-
case 0:
-
case 1:
-
/* ISO 10126 */
-
THIS->backlog[i] = DO_NOT_WARN((unsigned char)(my_rand() & 0xff));
-
break;
-
case 2:
-
/* ANSI X.923 */
-
THIS->backlog[i] = 0;
-
break;
-
case 3:
-
/* PKCS7 / RFC 3852 */
-
THIS->backlog[i] = DO_NOT_WARN((unsigned char)size);
-
break;
-
case 4:
-
/* Null only */
-
THIS->backlog[i] = 0;
-
break;
-
}
-
-
-
THIS->backlog[THIS->block_size - 1] = DO_NOT_WARN((unsigned char)size);
-
push_string(make_shared_binary_string((const char *)THIS->backlog, THIS->block_size));
-
-
THIS->backlog_len = 0;
-
-
safe_apply(THIS->object, "crypt", 1);
-
}
-
-
/*! @decl string(0..255) unpad(string data, void|int method)
-
*!
-
*! Decrypt and unpad a block of data. Neither the input or output
-
*! data is not automatically memory scrubbed, unless
-
*! @[String.secure] has been called on the data.
-
*!
-
*! This performs the reverse operation of @[pad()].
-
*!
-
*! @param method
-
*! The type of padding that was applied to the original buffer.
-
*! @int
-
*! @value Crypto.PAD_SSL
-
*! @value Crypto.PAD_ISO_10126
-
*! @value Crypto.PAD_ANSI_X923
-
*! @value Crypto.PAD_PKCS7
-
*! @value Crypto.PAD_ZERO
-
*! @endint
-
*! Defaults to Crypto.PAD_SSL for compatibility reasons.
-
*!
-
*! @seealso
-
*! @[pad()]
-
*/
-
PIKEFUN string(0..255) unpad(string str, void|int method) {
-
ptrdiff_t len;
-
int m = 0;
-
-
len = str->len + THIS->backlog_len;
-
if( len % THIS->block_size)
-
Pike_error("Total data size must be integral numbers of blocks.\n");
-
-
if( method!=NULL )
-
{
-
m = method->u.integer;
-
pop_stack();
-
args--;
-
}
-
-
f_Proxy_crypt(1);
-
if (TYPEOF(Pike_sp[-1]) != T_STRING)
-
Pike_error("crypt() did not return string.\n");
-
if (Pike_sp[-1].u.string->len != len)
-
Pike_error("crypt() Unexpected string length %ld.\n",
-
DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
-
str = Pike_sp[-1].u.string;
-
-
if( m==0 )
-
{
-
if (str->str[len - 1]+1 > THIS->block_size)
-
Pike_error("Invalid padding (%d > %d)\n",
-
str->str[len-1]+1, THIS->block_size-1);
-
}
-
else
-
if (str->str[len - 1] > THIS->block_size)
-
Pike_error("Invalid padding (%d > %d)\n",
-
str->str[len-1], THIS->block_size-1);
-
-
-
len -= str->str[len - 1];
-
switch( m )
-
{
-
case 0:
-
len--;
-
break;
-
case 4:
-
{
-
int c=THIS->block_size;
-
while( str->str[len-1]==0 && c>0 )
-
{
-
c--;
-
len--;
-
}
-
}
-
}
-
-
if (len < 0)
-
Pike_error("String too short to unpad\n");
-
-
add_ref(str);
-
pop_stack();
-
push_string(make_shared_binary_string(str->str, len));
-
free_string(str);
-
}
-
-
/*! @decl this_program set_iv(string iv)
-
*! Set the initialization vector to @[iv].
-
*/
-
PIKEFUN object set_iv(string iv)
-
optflags OPT_SIDE_EFFECT;
-
{
-
apply(THIS->object, "set_iv", args);
-
args = 1;
-
RETURN this_object();
-
}
-
-
}
-
-
/*! @endclass
-
*/
-
+
#if 0 /* @class LFib * The Donald Knuth Lagged Fibonacci pseudo random number generator. * This is @b{not@} a source for cryptographic randomness. Use * @[Crypto.Yarrow] instead. */ PIKECLASS LFib { CVAR struct knuth_lfib_ctx *ctx;