[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [GNUnet-developers] Playing with GNUnet

From: peter
Subject: Re: [GNUnet-developers] Playing with GNUnet
Date: 11 Jul 2002 21:28:47 -0000

>> I presume you've already heard the suggestion that you migrate from
>> Blowfish to AES.  530 encryption operations to schedule 4K of S-boxes
>> just to do 128 encryption operations per 1K payload seems... excessive.

> Yes, but OTOH, it does not seem to matter. CPU load is not really a concern.

It's just a general principles "don't be wasteful" thing to keep in mind
for the next time you make a major version change and invalidate
everything anyway.

>> The promised FAQ entry on disk usage efficiency and ext2 doesn't
>> seem to exist.  I presume that it's telling me that my current
>> file system parameters of 4K blocks and 16K bytes/inode will
>> not work very well for GNUnet, which wants 1K for each.

> Where is that one mentioned? We're now using gdbm, so this entry was removed. 
> Must be a dead reference, but where did you find it?

At least two places, as I recall.  Let's see...

>> One problem with the 1K block size is that, since you don't have any
>> inter-block mixing, it might be vulnerable to code book attacks for
>> low-entropy sources.  Unfortunately, some file-wide mixing might
>> remove the easy random-access you have right now.

> You are mistaken in the purpose of the encoding. Deniability does not require 
> that it is *impossible* to break the cipher, just 'unreasonable to assume to 
> be done by an intermediary/router'. Code book attacks work on any hash-based 
> system.

H'm... you're right that I have to do some thinking.

>> One possible solution would be to define the encryption key e_i for
>> block i with parent block j, to be not equal to h_i, but e_i = f(h_i,
>> e_j), for some suitable combining function f (perhaps XOR?).  For this
>> purpose, the root's e_j is taken to be 0.
>> This makes the ciphertext for the whole file depend on the hash of the
>> whole file, without requiring any more data than is already present in
>> the indexes.

> Again, it's fine if you can in some cases break the encryption. We want so 
> SHARE files, not hide them. As long as I can reasonably claim that I did not 
> know what was on my drive (because I could not trivially break the cipher), 
> deniability (deny knowledge of the content stored or routed) is achieved.

A little bit of thinking reveals the following "attack":
- Suppose I wish to suppress some specific samizdat of length >1K,
  e.g. I'm a Scientologist and I want to stop people quoting the NOTs.
- I generate all possible 1K windows of the material in question,
  encrypt them and hash them.  This produces output 20 times as large as
  the document I want to suppress.
- I get a court order forbidding people to serve blocks with the given
  hashes.  I haven't revealed the plaintext, but I've (partially) defeated

This can be defended against by altering the quoted plaintext:
punctuation, spacing, line-wrapping, or the like, but why should the
system user have to go to the trouble?

I agree that the value of having multiple insertions of the same
plaintext "collide" and merge is significant.  Is accidental
sharing of matching *blocks* in different plaintext sufficiently
likely to be worthwhile?

>> I'm not quite sure how to interpret the daemon's debugging output, but
>> it occurs to me that TTL values could be made more deniable.  An easy
>> one would be to change to only decrementing them half the time (and
>> halving the initial value to compensate).  Thus, just because I sent
>> a query with a given TTL doesn't mean that I (or one of my peers)
>> originated it...

> Since initial TTLs are chosen with a random factor in them (they are NOT 
> constant), you can not say 'TTL 5 means it's 5 hosts away since they start at 
> 10'. Decrementing only half of the time may make cycle detection much worse, 
> thus this is not a good idea.

(I should check the source, but...) are the TTLs chosen from an infinite
(e.g. normal) or finite (e.g. uniform window) distribution?  The latter
allows definite statements about the locaiton of the source of query to
be made, particularly any time a value near the limit of the possible is
seen.  An infinite distribution just makes is less likely.

The sometimes-decrement is basically a cheap way of generating an
infinite TTL range, with the added bonus of obscuring cycle lengths
as well.

I'm not sure how it can make cycle detection a problem.  If *all* nodes
on a cycle fail by *never* decrementing the TTL, a packet will loop
forever, but that's true no matter whan the decrementing rule.

It does make it harder to *measure* the number of hops in a cycle, but
I'm not sure why you'd want to do that anyway.  Maybe there's some
specific operation done in the source that I should look into.

>> gnunetd really should fork into the background once it's completed
>> initialization, like a good daemon.  While I can just run it in the
>> background in the first place, that makes it impossible to check for
>> errors.

> Sounds like a good idea, but since I never wrote a good deamon (mine are 
> always evil :-), I am not certain where exactly to do it and how to ensure 
> that everything is fine. Care to provide a patch?

Okay, I get the hint. :-).  Have a look at Stevens "Advanced Programming
in the UNIX Environment", section 13.3 (Daemon Processes: Coding Rules).
The basic technique is:

        /* Open all files, network connections, etc. */
        /* Don't hold the wrong FS mounted */
        if (chdir(some_suitable_directory) < 0) {
                return 1;
        if (umask(0) < 0) {
                return 1;
        logfd = open("/path/to/log/file", O_WRONLY | O_CREAT | O_APPEND);
        if (logfd < 0) {
                return 1;
        nullfd = open("/dev/null", O_RDWR);
        if (logfd < 0) {
                return 1;
        if (!debug_flag) {
                pid_t pid = fork();
                if (pid < 0) {
                        return 1;
                if (pid) {
                        /* Parent */
                        /* print pid of child for /var/run/ */
                        printf("%u\n", (unsigned)pid);
                        _exit(0);       /* Avoid atexit() problems */
                /* child - close fds linking to invoking terminal, but
                 * close usual incoming fds, but redirect them somewhere
                 * useful so the fds don't get reallocated elsewhere.
                if (dup2(nullfd,0) < 0 || dup2(logfd,1) < 0 || dup2(1,2) < 0) {
                        perror("dup2"); /* Should never happen */
                        return 1;
                pid = setsid(); /* Detach from controlling terminal */
                log_entry("Child backgrounded, pid = %u", (unsigned)pid);
        /* Main loop goes here */

> Sounds like a bug. Added to the pile...

Thanks.  Looking at it is tricky:

> Mantis - OVM Bugtracking
> ERROR: your account may be disabled or the username/password you entered
> is incorrect.
> [ Click here to proceed ]

Does Mantis require cookies enabled or some such?

>> I notice that gnunet forks children which spend a lot of time in
>> loops like:
>> getppid()                               = 17459
>> poll([{fd=8, events=POLLIN}], 1, 2000)  = 0
>> getppid()                               = 17459
>> poll([{fd=8, events=POLLIN}], 1, 2000)  = 0
>> getppid()                               = 17459
>> poll([{fd=8, events=POLLIN}], 1, 2000)  = 0
>> getppid()                               = 17459

>> There is an easy way to block on the parent exiting, using a pipe.
>> Create a pipe which only the parent can write to (children close the fd
>> after forking), and it will poll ready-to-read (EOF) when the parent exits
>> (and closes the write end).

> This must have something to do with our use of pthreads. What is odd
> that on my machine(s), gnunetd takes only a couple of minutes of total 
> CPU time over weeks. What system are you using? Is it really an issue? 
> Since we're not explicitly calling getppid(), the above is definitely a very
> low-level remark, so I'm also not sure where to even start to fix it (if it
> is really an issue).

strace() is my general "What is this thing doing?" probe.
Yes, it might easily be a pthreads thing.  

The system is an x86 running Debian GNU/Linux (unstable), with kernel
2.4.18 (+ nanokernel patches).

The reason this is an issue is that the constant activity increases
the memory footprint of an idle daemon.  Of course, sending noise
packets does that too, and that's necessary...

> That must be the cron-job. It checks every second if there is "more
> work". Why it should call time that often is a mystery to me, though.

I'm going to have to look into that, I suppose.  Perhaps I can create
a version that doesn't busy-loop, but computes when it wants to wake up
and sleeps until then.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]