Live data from Hacker News

Notes by djb on using Fil-C

cr.yp.to

251–260 of 263 posts

Re: Notes by djb on using Fil-C

#251
post #116

Earlier quoted context omitted.

Note that Fil-C is a garbage-collected language that is significantly slower than C. It's not a target for writing new code (you'd be better off with C# or golang), but something like sandboxing with WASM, except that Fil-C crashes more precisely.

WASM is a sandbox. It doesn't obviate memory safety measures elsewhere. A program with a buffer overflow running in WASM can still be exploited to do anything that program can do within in WASM sandbox, e.g. disclose information it shouldn't. WASM ensures such a program can't escape its container, but memory safety bugs within a container can still be plenty harmful.

You can buffer overflow in fil-c and it won't detect it unless the entire buffer was its own stack or heap allocation with nothing following it (and also it needs to be a multiple of 16 bytes, cause that's padding that fil-c allows you to overflow into). So it arguably isn't much different from wasm.

Quick example:

typedef struct Foo {

    int buf[2];

    float some_float;
} Foo;

int main(void) {

    Foo foo = {0};

    for (size_t i = 0; i 
}

This overflows into the float, not causing any panics, printing 0.5 for the float.

Re: Notes by djb on using Fil-C

#252
post #116

Cool project! I take it the goal is that, overhead being acceptable, most C / C++ programmes don't actually "have to be" rewritten in something like Rust? I wonder how / where Epic Games comes in?

Note that Fil-C is a garbage-collected language that is significantly slower than C. It's not a target for writing new code (you'd be better off with C# or golang), but something like sandboxing with WASM, except that Fil-C crashes more precisely.

Test with Fil-C, compile with gcc into production. Easy.

Re: Notes by djb on using Fil-C

#253
post #49

Earlier quoted context omitted.

I would say that Rust would be a better choice rarher than patching memory safety on top of C. But I think the reason for this is that most, if not all, cryptographic reference implementations are in C. So they want to use existing reference implementations without having to port them to Rust. IMO cryptographers should start using Rust for their reference implementations, but I also get that they'd rather spend their…

Memory safety is a very small concern for most cryptographic implementations (e.g Side Channel attacks). Rust solves essentially none of the other concerns.

IIRC SHA3's reference implementation had an integer overflow in a counter that made finding collisions trivial, as it meant that some blocks of the input weren't considered.

Re: Notes by djb on using Fil-C

#254
post #228

Earlier quoted context omitted.

I tried it on my primes micro-benchmark ( http://hoult.org/primes.txt ) and got a 2:1 slowdown on 13th gen i9. It does a LOT of array access and updating, probably near to worst-case for code that isn't just a loop copying bytes. The average slowdown is probably more in the same region as using Java or C# or for that matter C++ std::array or std:vector.

If you missed it, djb himself posted this cute graph of "nearly 9000 microbenchmarks of Fil-C vs. clang on cryptographic software (each run pinned to 1 core on the same Zen 4)": https://cr.yp.to/2025/20251028-filcc-vs-clang.html I've heard Filip has some ideas about optimizing array performance to avoid capability checks on every access... doing that thread safely seems like an interesting challenge but I guess there…

Sure of course I followed that link. I've really got no idea what the horizontal axis is! But there is a huge cluster of results between 1x and 1.5x execution time.

And, the kind of code he is interested in is not necessarily the same as the kind of code I'm interested in. In fact I know it's not!

As one more data point, compiling my little benchmark with gcc, without any optimisation flag.

     1964ms gcc primes.c -o primes -O
     3723ms fil-c primes.c -o primes -O
     3753ms gcc primes.c -o primes
    16334ms fil-c primes.c -o primes
Fil-C with -O is almost identical to gcc without.

Re: Notes by djb on using Fil-C

#255

Earlier quoted context omitted.

Abstractions are the only way to make sense of cryptography. Pretending otherwise leads to cross layer bugs and vulnerabilities. Of course bad abstractions are bad, but that doesn’t mean no abstraction is good. Feel free to post your challenge snippet.

pub fn read >(path: P) -> io::Result > { fn inner(path: &Path) -> io::Result > { let mut file = File::open(path)?; let mut bytes = Vec::new(); file.read_to_end(&mut bytes)?; Ok(bytes) } inner(path.as_ref()) } "aBsTraCtiOnS aRe gOod"... Right. Reference implementations must NOT have abstractions like this. Rust encourages it. Lots of Rust codebase is filled with them. Your feelings for Rust is irrelevant. C is simple…

(a) that is a fairly easy to understand piece of code. Are you complaining about the definition of the inner function?

(b) the equivalent C code would look pretty similar.

(c) this is not cryptographic code

Re: Notes by djb on using Fil-C

#257
post #90

Earlier quoted context omitted.

There's a contingent of rust fans that show up on every story about C – their premise is that C code is unsafe and most safety-critical C code should be rewritten in rust. Fil-C is new and is a viable competitor to rust, that's why you're hearing all asides about tiny niches, unacceptable performance degradation, etc.

Hacker News is not a place where any one group brigrades a thread. There are people who prefer C who don't want a GC, people who prefer Rust who don't want C, people who prefer Rust who agree with Fil-C for legacy C, people who don't prefer C or Rust and may use languages with GC.... We all have interests and face people who denigrate them in bad faith. If you have specific objections to inaccurate statements in this…

> Hacker News is not a place where any one group brigrades a thread

Sweet summer child

Re: Notes by djb on using Fil-C

#258

Earlier quoted context omitted.

pub fn read >(path: P) -> io::Result > { fn inner(path: &Path) -> io::Result > { let mut file = File::open(path)?; let mut bytes = Vec::new(); file.read_to_end(&mut bytes)?; Ok(bytes) } inner(path.as_ref()) } "aBsTraCtiOnS aRe gOod"... Right. Reference implementations must NOT have abstractions like this. Rust encourages it. Lots of Rust codebase is filled with them. Your feelings for Rust is irrelevant. C is simple…

(a) that is a fairly easy to understand piece of code. Are you complaining about the definition of the inner function? (b) the equivalent C code would look pretty similar. (c) this is not cryptographic code

(a) I'm complaining about the messed up syntax and symbol soup.

https://github.com/ioccc-src/winner/blob/master/2024/burton/...

This code is fairly easy to understand, too, then.

(b) No, it would definitely not look "pretty similar".

(c) So what? You talked about abstractions in cryptographic code. Abstractions are layers to hide things. That is bad in crypto code.

Re: Notes by djb on using Fil-C

#259

Earlier quoted context omitted.

It's amazing how much technical discourse revolves around impressions. "Oh, it has a GC! GC bad!" "No, this GC by smart guy, so good!" "No, GC always bad!" People aren't engaging with the technical substance. GC based systems and can be plenty good and fast. How do people think JavaScript works? And Go? It's like people just absorbed from the discursive background radiation the idea GC is slow without understanding w…

> It's amazing how much technical discourse revolves around impressions. One of the single most incisive comments in the whole discussion. My take: people don't take the time to even try to understand some things of only moderate complexity. They dismiss it as "too hard", drop it, accept the received wisdom and move on. This is also behind the curse of "best practice". After coming up on 40Y in the industry, my impre…

This article bears directly on my point:

Why Engineers Can't Be Rational About Programming Languages

Steve Francia 3 Nov 2025

The Leadership Blindspot: How Identity Drives Multi-Million Dollar Technical Debt

https://spf13.com/p/the-hidden-conversation/

Re: Notes by djb on using Fil-C

#260
post #24

Earlier quoted context omitted.

So far we haven't found a viable alternative; CHERI has holes in its temporal integrity guarantees.

Both Fil-C and CHERI rely on a concurrent GC/a GC-like task to find and invalidate all pointers to free()'d memory objects (in "quarantine") before putting them back into the memory pool. The difference is that because Fil-C has bounds in each object's header, it only has to nullify it to remove access whereas in CHERI a quarantined object can still be accessed through any pointer that hasn't been invalidated yet. I'…

Follow-up: CHERioT (Microsoft's RV32E-based variation for embedded systems) does have a quarantine tag bit per 64-bit word of memory. The base address' bit is checked on capability load by the CPU's "Load filter".
Post reply on HN