25,077 karma · joined October 1, 2012
One could (but maybe shouldn’t) eat a bonito flake or two as an experiment.
But the actual behavior, at least for the SGP4x series, is so outrageously unstable and path dependent that you still can’t learn the value if that function of the gas concentrations. At best you get changes on timescales of minutes to a few hours but not on timescales of days.
https://sensirion.com/media/documents/296373BB/6203C5DF/Sens...
I’ve personally played with the SGP41, but I’m guessing the poster I replied to has the SGP40 because they didn’t mention NOX Index.
The instrument is pretty crappy - it has basically no calibration or, AIUI, long term stability. So you can’t really use it to characterize the chemical content of the air. What you can do is observe changes. I’m guessing the manufacturer wanted to avoid people getting confused by the absurd raw reasons, so they came up with a formula called “VOC Index” that HPFs the data. It will average 100 IIRC. You’re supposed to use it to notice events that cause changes - if it hits 170 every day at 2 PM them you can guess that something’s happening at 2 PM.
None of this is in the chip. It’s implemented by the driver. There’s an implementation in esphome, for example.
I target 0 PM2.5, but this only necessarily makes sense as a target if you have the ability to filter your home's supply air. And a good vent hood should be able to avoid any detectable bump while cooking (although a vent hood without filtered makeup air may cause a bump due to increased infiltration of exterior air).
All of these algorithms are neat but utterly ridiculous :)
Interestingly, the operations discussed in this part of the note are, I think, pretty much exactly the operations needed to operate on classical representations of an m-qubit quantum state, implementing single-qubit unitary quantum gates on each qubit.
I suspect that, if you had asked me fifteen years ago if I thought you could do the same exact operations like this on each of n different states (on a classical computer) faster than n times however long it would take to do it once, I would have said “sure, why not?” It probably helps that I worked with people who really liked matrix multiplication and similar problems :)
For fun, I have ChatGPT Pro chewing on the following prompt:
Suppose I have a m-qubit quantum state. I can do an operation U = U_1 \otimes ... \otimes U_m, which is just a unitary operation on each individual register.
I can also simulate this on a classical computer. Start with the state, written out classically as a complex amplitude for each state in the computational basis (i.e. 2^m complex numbers). U acts on this state in a linear manner to produce a new state. What's the classical time complexity of this? (Assume a model of computation with exact complex addition, multiplication, conjugation, etc taking unit time, but don't cheat by encoding absurd things into complex numbers. Assume data movement is free.)
Now suppose I want to apply the same U to n separate input states. Can I do better than n times however long it takes to do the operation once?
Heck, I can do this too, with my eyeballs and brain! Just slower and will less overall memorized knowledge than modern LLMs.
I can maybe see how one might have a MutexGuard for the entire RenderState and then pass an owned MutexGuard<PartOfTheState> somewhere else, but this seems like it should not be necessarily be able to coexist with other guards holding the same mutex.
How would split guards work, anyway? Reference counts on parts of the mutex? Would the mutex have to opt in? Is there an actual example where splitting a mutex guard would be useful!
> For example, how to turn (the handle for) a MutexGuard<RenderState> into a MutexGuard<String> when the programmer writes state.template.
Please don’t. In the examples later in the article, maybe an Option<&A> can be dereferenced and projected to get an optional reference to something inside the A. Fine — Option is logically a value, and you either have a reference or don’t have a reference.
But a MutexGuard is not just a value. It’s a representation of a lock held on a particular mutex. Dropping it has side effects! If I have a MutexGuard<RenderState>, this means that there is a Mutex<RenderState> and that, when the guard drops, the mutex unlocked. A field in the RenderState should not have a guard unless it has its own mutex!
ISTM what’s actually wanted for mutex guard field projections is one of two things:
1. Nicer syntax. The article points out that this works today:
let state: &mut RenderState = &mut *state.lock().unwrap();
Great! Improve the syntax! Or:2. Use the new machinery to make the actual motivating example work without making up a MutexGuard where none should exist. Have the field projection return an ordinary reference. Is this harder for some reason that having it return MutexGuard?
I'm not sure it needs to map out this way. In the last few years people have gotten used to the idea that ACME means that the client interacts directly with the actual CA, but there's another model that at least used to be widespread: certificate brokers. Right now, I tell my ACME cliejnt to get me a Let's Encrypt certificate, and Let's Encrypt validates my request and makes it happen.
But what if I instead tell my ACME client to talk to a broker? The broker would arrange with various CAs for whatever portions of the overall namespace it supports, and it would give me TOS that those CAs find acceptable. And it would then forward my requests to appropriate backend CAs, and those backend CAs would (and would be required to by CA/B rules) validate my request. And I'd get a cert without particularly caring who the backend CA is.
The root stores would treat the backends as fully responsible for validation.
I don't know whether the current ACME model actually supports this very well. The tricky bits I can imagine mostly involve ACME account identification, CAA record details and dns-persist-01. If I authorize my ACME account (held with the broker) for my domain, the backend needs to be able to validate, in a manner that the broker cannot forge except to the extent that it's unavoidable. So if I have account 12345 (just an identifier), then I think the backend should be able to trust the broker's assertion that the client really did convince it (with replay protection) that it's the client for account 12345. But if I have an account where the account itself indicates a public key, then the broker should not be able to forge it.
In any case, I think it's vaguely ridiculous that, right now, the UK government has essentially no say in whether Let's Encrypt may issue certificates for .gov.uk domains. (This is just an example.)
Meanwhile there are two less invasive changes that really ought to happen:
1. A clean way for things like curl and Python to start checking CT logs like Chrome does.
2. Name constraints. It’s long past time for the CAs of the world to have name constraints enforced. A CA that is not appropriate to use for .com should not work for .com. A CA that is not appropriate to use for .ae should not work for .ae. And the CA/B Forum should should requiring that all newly approved roots and all newly signed intermediates have appropriate name constraints.
Once the private key has been leaked, this is basically all pointless.
Can a site owner trust that a certificate in their name has been logged? Of course not! An attacker could be signing it on the fly.
Can an auditor read the complete record? The complete record is kind of meaningless if the private key is leaked. But the auditor already knows that the private key is leaked!
Will the CA get caught if they issue a cert that isn't in the log? Yes! In fact, all newly signed certs won't be in the log.
Will browsers that check for log inclusion be protected? Yes, because newly signed certs won't be in the log.
Will anyone who sees a signed cert that isn't in the log hold evidence of misbehavior? Yes!
One might argue that the actual change to the CT system that should be made is a way for a CT operator to insert a statement into the append-only log that they believe a signing key to be compromised and that they will therefore no longer accept certificates signed by that key.
But the relevant bit is at the end, from “if” to “return”, and should be pretty accessible to anyone familiar with an imperative language who can get past the general ugliness of the code. Once that’s figured out, you can recover the password by copying and executing the rest of the function.
The bugzilla issues mentioned elsewhere suggest at least a mostly orderly removal of trust with issuance stopped several months ago. Your new cert was issued by “CN=EM DV TLS CA - G3B,O=eMudhra BV,C=NL”, which presumably chains to the G3 root, and the bugzilla issue seems to say that G3 was going to be dropped from the root lists some time ago but that maybe it would be cross-signed by something still trusted. So I assume that something else is going on.
Was that cert issued via normal means (e.g. ACME)?
(Or just add the vectors instead of using wider vectors - everyone seems to have good results from munging vectors together with plain addition.)
Would it really have been so hard to encode an indication of whether use of the public Internet is permissible in the prompt and to train the models to not attempt to exceed authorized access?
The whole succeed-at-all-costs idea is a big part of why there have been so many massive security screwups lately.
How confident are you that the flying object in that video is a car?
Some cursory estimates suggest that one really could get several seconds of operation with enough thrust to lift a real car with a big motor and battery and seats and such, but the margins are not great. If I were designing this thing and I cared more about showmanship than about demonstrating an actual credible car, I might use the tiniest battery I could find with adequate power output (lithium titanate? small LFP?), as little motor as I could get away with, and no interior amenities whatsoever.
More cynically, I would also contemplate whether I really really needed the fancy downforce fan for this demo. After all, that’s a very controlled track and I can imagine other ways of getting a car up it.
If you write:
if (a)
breakpoint();
other code;
Then there two obvious ways for code to be generated, one of which puts the address after int3 in the wrong basic block.In a good enough debugger insn length might not matter - there will be a choice of addresses, ask all belonging to the next instruction. Subtracting one and handling the case where the address is in the middle of an instruction should be good enough.
(Or just track whether the address in question is the start or end of the insn. Keep in mind that, in basically every architecture, call saves the next address, not its own.)
But let’s be clear. ptrace() is unbelievably crappy, and gdb is approximately as crappy.
> Implementations are expected to optimize the code generated to be as minimal as possible for the platform. For example, on X86 it’s expected that this produces a single INT3 instruction. The goal in this expectation is to place the debugger as close as possible in the caller of breakpoint() to improve the debugging experience for users.
This is the wrong design on x86 at least with many debuggers. x86’s int3 is a trap and reports the address of the next instruction in the saved register state [0]. Most debuggers are not very clever and just use the saved address to generate the offending line of code and the call stack. But if the trap sequence is just int3, then the saved address could be outside the offending basic block or even outside the function entirely. gdb is certainly in the class of debuggers that get this wrong.
The easy workaround is to generate int3; nop for the breakpoint instead of just int3. The saved address will point to the nop and the debugger will be happy.
[0] FRED also reports the instruction length, allowing one to deduce the trapping address.