Hacker-Proof Code Confirmed - <AUTHOR> https://www.quantamagazine.org/20160920-formal-verification-creates-hacker-proof-code/ <comment><USER2> I'm one of the researchers at Galois who's working on the quadcopter platform for HACMS. Let me first say that this headline makes me cringe just as much as anyone. I'd also like to give folks a pointer to some of the work we've developed on the project–it's all open source.

First we have Ivory, the DSL for doing safe systems programming that takes buffer overflows and other memory-safety bugs off the table: [http://ivorylang.org/](http://ivorylang.org/) [1]

Second, the flight control software we wrote for the 3DR Iris+: [http://smaccmpilot.org/](http://smaccmpilot.org/) The adventurous among you who fly with a Pixhawk can build it and try it out yourselves, and we'd love to hear your thoughts.

[1]: When we began work on HACMS, Rust was around but nowhere near mature enough to base a proposal on. These days, it covers a lot of the same bases, although currently Ivory is more suited for formal analysis with SMT solvers and model checkers.

<comment><USER3> Glad to hear you say that.

Aside from that the work seems very interesting. I am going to check out Ivory. I have been reading up and playing with Idris and F _.

I like F_ so far, and that you can output F# and OCaml. Idris's goals seem in line with what you were originally looking for. Have you evaluated it?

<comment><USER2> Indeed, we're fans of Idris here, and even hosted a series of Idris tech talks: [https://galois.com/blog/2015/01/tech-talk-dependently- typed-...](https://galois.com/blog/2015/01/tech-talk-dependently-typed- functional-programming-idris-1-3/)

The goals of Idris and similar languages are different from the goals we had with Ivory, though. We sometimes describe Ivory as "medium-assurance" as opposed to the high assurance one can get from a language with a more expressive type system.

It makes sense for some systems or components to be formally verified, for example the seL4 verified microkernel which is also used on our copter. However we simply would not have been able to formally verify (or even get to typecheck with fancier dependent types) something on the scale of an autopilot given the resources we had on the project. Instead we rely on getting quite a bit of bang for the buck with the memory safety features, and then augment with assertions.

We ended up with a working autopilot (and board-support package with drivers) in only ~4 engineer-years, so we think the tradeoff is working well so far :)

<comment><USER3> Sounds great. I'll check out the talks link and Ivory some more. Thanks!

</comment></comment></comment></comment><comment><USER4> Quick reminder that verified code is only hacker-proof provided that:

a) The specification correctly describes all correct behavior and correctly proscribes all incorrect behavior (basically, you trade a huge codebase for a smaller one in the form of the spec, which is a massive improvement, but as long as humans write the spec it is not clear it can ever be fully hacker- proof)

b) The trusted computing base works as modeled in the spec. Even on the limit, that means that the physical properties of the hardware are as we expect them to be and that our understanding of the laws of physics is correct. Slightly below this threshold there are things like Row Hammer attacks ([https://en.wikipedia.org/wiki/Row_hammer](https://en.wikipedia.org/wiki/Row_hammer) ). Before even this: microcode bugs, proof-verifier bugs, etc.

That said, formal methods do provide a huge improvement over the state of the art of completely unspecified software, and have been shown to work in practice to greatly reduce the number of vulnerabilities of important large systems such as compilers, kernels and now remote controlled helicopters. They might not be appropriate for every piece of software quite yet, but I would greatly like to see this stuff for things like self-driving cars, airplane autopilots, smart grids and smart factories and in general all of the rapidly approaching "heavy" IoT applications. Also, some verified properties of commodity OS would be very nice to have (say container isolation in a cloud environment or non-leaking of keys for a smart wallet process).

<comment><USER5> > basically, you trade a huge codebase for a smaller one in the form of the > spec

Most formally verified things i have seen require huge amounts of 'spec' code compared to the implementation.

<comment><USER6> You're confusing the specification with the equivalence proof. A spec is likely going to be about as simple as an implementation, with the benefit that it can be read more consistently.

<comment><USER7> All the specs for real world things I've seen are long and use fuzzy language. Making them formal enough to provide a basis for verification will only make them longer.

<comment><USER8> I wouldn't be so pessimistic about the possibility to produce useful specifications of real-world systems.

One recent successful large-scale verification is the CompCert C compiler. The compiler is verified relative to a formal specification of a large subset of C. This specification is in the order of <2000 lines of Coq code (see [http://gallium.inria.fr/~xleroy/publi/Clight.pdf](http://gallium.inria.fr/~xleroy/publi/Clight.pdf) ). So it is an example of a specification that is much smaller than an implementation and that can be verified manually.

Also, there is good evidence that the specification is correct. From [https://www.cs.utah.edu/~regehr/papers/pldi11-preprint.pdf](https://www.cs.utah.edu/~regehr/papers/pldi11-preprint.pdf) :

> The striking thing about our CompCert results is that the middle- end bugs > we found in all other compilers are absent. As of early 2011, the under- > development version of CompCert is the only compiler we have tested for > which Csmith cannot find wrong-code errors. This is not for lack of trying: > we have devoted about six CPU-years to the task.

</comment></comment></comment></comment></comment><comment><USER9> > "We're not claiming we're going to prove an entire system is correct, 100 > percent reliable in every bit, down to the circuit level," Wing said. > "That's ridiculous to make those claims. We are much more clear about what > we can and cannot do."

This is an important statement that should be highlighted more prominently in the article (whose title I disagree with).

Formal methods are promising, and I'm glad that the researcher acknowledged that when your project relies on so many other abstractions and systems it doesn't matter how rigorously developed your solution is if a hacker can find a way to accomplish their objective through one of your dependencies.

<comment><USER10> Specifically, hardware level exploits are wholly disregarded by formal verification. This means bit-banging could still work. In many systems I'd also be wary of the OS itself.

<comment><USER11> They're disregarded by _software_ verification. There's more formal verification deployed in hardware than software. There's also techniques to verify hardware and software together. The hardware problems you see are often deliberately left in there either due to corner cutting or backward compatibility with bad designs of the past. Both inspired by desire to see the number next to net income continue to rise. ;)

</comment></comment></comment><comment><USER12> I Google'd _HACMS project_ and found an Open Catalog page at DARPA with a bunch of links to open source software and paper PDFs.

Seem worth checking out to anyone whose interest was piqued by the article.

[http://opencatalog.darpa.mil/HACMS.html](http://opencatalog.darpa.mil/HACMS.html)

</comment><comment><USER13> Has anyone successfully brought formal methods to an area of code that is _newly_ being developed?

I have successfully convinced management to allow me to use formal methods on portions of very old code (~17 years old at the time) that are being rewritten.. but I've never been able to get management on board with the time required for new development with formal methods. The planning time up-front is more than what a lot of companies are willing to tradeoff for time-to- market.

<comment> Ben-G Amazon has made use of formal methods during the development of AWS. Relevant paper can be found here: [http://cacm.acm.org/magazines/2015/4/184701-how- amazon-web-s...](http://cacm.acm.org/magazines/2015/4/184701-how-amazon-web- services-uses-formal-methods/abstract)

<comment><USER13> Found a much better link :)

[http://research.microsoft.com/en- us/um/people/lamport/tla/fo...](http://research.microsoft.com/en- us/um/people/lamport/tla/formal-methods-amazon.pdf)

</comment></comment></comment><comment><USER14> A while back I was exploring the use of 'soft' formal methods to help in evaluating correctness of some new modules we had to develop. I had come upon Alloy, which seems like a gentler introduction to formal methods (Unlike Z or Coq).

[http://alloy.mit.edu/alloy/](http://alloy.mit.edu/alloy/)

Anyone have any experience using Alloy, or some other formal method?

<comment><USER15> I've used it several times but the big problem with it is that once you have a nice, correct model that has been checked (and no counterexamples found), there's no way to translate it to code. This meand that your basically back on square one in terms of implementation.

I really like (and use quite often) the ASM method instead.

More of my thoughts here: [http://ortask.com/how-i-designed-built-and-tested- a-temperat...](http://ortask.com/how-i-designed-built-and-tested-a- temperature-logger-with-arduino-part-2/)

<comment><USER11> There's actually been imperative extensions and prolog compilers for it. Here you go:

[https://homes.cs.washington.edu/~emina/pubs/alloy.mscs13.pdf](https://homes.cs.washington.edu/~emina/pubs/alloy.mscs13.pdf)

Also, for ASM's, the most interesting one I've seen is certified compiler project that is taking a lot less lines of code than CompCert:

[https://www.complang.tuwien.ac.at/andi/papers/hipeac14.pdf](https://www.complang.tuwien.ac.at/andi/papers/hipeac14.pdf)

</comment></comment></comment><comment><USER16> Can we get an actual example of a formally verified piece of code? If I have a function adding a and b, how does it look when it's "formally verified"?

<comment><USER11> Good news is that most of them abstract the stuff away for common operations. They'll let you annotate code that's transformed into a set of verification conditions that the prover automatically discharges. SPARK is an example:

[http://www.skein-hash.info/SPARKSkein-release](http://www.skein- hash.info/SPARKSkein-release)

Let's say that work isn't done. Then you have to hand model the properties of what you're doing. Arithmetic, expressed in bits, is harder than it appears to describe in a way that covers all the properties. Here's one on SmartMIPS:

[https://staff.aist.go.jp/reynald.affeldt/documents/affeldt-j...](https://staff.aist.go.jp/reynald.affeldt/documents/affeldt- jssst2006-en.pdf)

</comment></comment><comment><USER17> Although good, hasn't this just shifted the burden up a level?

With formal methods, we can get proven-ish correct implementation, now we need bug-free specifications.... this in itself will be the next challenge.

In the real world, specifications are very incomplete and fuzzy, partly because the business-level specifications are also fuzzy.

This will not be a panacea, its simply shifted the burden up to a (possibly more manageable) level.

<comment><USER11> "With formal methods, we can get proven-ish correct implementation, now we need bug-free specifications.... this in itself will be the next challenge."

That's _much_ better. See, before you needed to (a) understand a vague specification, (b) get your concrete version of it right, and (c) implement that specification. Now, you just trust a precise specification. That it's precise, esp if in Z or something, let's you check it against the people giving you vague stuff too by asking them questions. Solves lots of problems.

Altran/Praxis Correct-by-Construction provides an illustration of how that works:

[http://www.anthonyhall.org/c_by_c_secure_system.pdf](http://www.anthonyhall.org/c_by_c_secure_system.pdf)

At another extreme, some companies capture requirements in formal logic then just compile them to code with logic programming languages like Mercury:

[http://www.missioncriticalit.com/development.html](http://www.missioncriticalit.com/development.html)

Note: Not sure how well the last one works but worth mentioning that it's at least possible to go from specs to code in some places.

</comment></comment><comment><USER18> For anybody interested in this field:

Specifying Systems by Leslie Lamport, the same guy that gave us Logical Clocks and Paxos (free on Ms Reseach website):

[http://research.microsoft.com/en- us/um/people/lamport/tla/bo...](http://research.microsoft.com/en- us/um/people/lamport/tla/book-02-08-08.pdf)

</comment><comment><USER19> Aside from the obvious point that software can obly be as secure as the hardware it runs on, isn't Gödel's incompleteness theorem a problem with scaling from smallish problems to biggish ones?

Granted it has been a long time since I understood it even moderately well, but my main recollection is that a complete system of logic can't be consistent, and a consistent system can't be complete. That would seem to be an issue with extending formal methods to any computer system of broad general use.

Or am I misapplying the theorem here?

<comment><USER20> Gödel's incompleteness theorems are more of a theoretical limitation than a practical one.

Roughly speaking, Gödel's incompleteness theorems say that all proof systems for number theory are limited in some way. For example, first-order Peano arithmetic is such a system, and one of its limitations is that it doesn't support transfinite induction. (It doesn't matter if you don't know what it is.) In other words, if you want to translate a mathematical proof to Peano arithmetic, you have to come up with a way to do it without transfinite induction. Sometimes, such in the case of Goodstein's theorem, this is impossible. To prove Goodstein's theorem, you have to choose a stronger proof system to begin with.

So, Gödel's theorems guarantee that no matter how strong you proof system is, there are always number-theoretic statements that are beyond its reach. But for reasons that are not currently completely understood, this doesn't really happen in practice. "Naturally occurring" examples of number-theoretic statements almost always turn out to be provable in surprisingly weak systems.

Instead, you run into practical problems: the theorem is provable in the system, but actually writing out the proof is utterly inconvenient. As an analogy, there are Turing-complete programming languages that don't have the concept of functions. In theory, they are capable of all kinds of computations, but in practice you don't want to use them.

And if, instead of mathematics, we concentrate on proofs of correctness, then this is even less of a practical problem. To quote Leslie Lamport, proofs of correctness "are seldom deep, but usually have considerable detail." The proofs may be long and complicated, but as long as they don't use any kind of ridiculously abstract techniques, they are just the kind of proofs where computers can have an advantage over humans.

<comment><USER19> Interesting. Thank you for the explanation!

</comment></comment></comment><comment><USER21> I have always been interested in this area of programming. One thing I have always wanted is the ability to enforce restrictions on data types beyond memory. By that I mean say i am using an int, what if I want to restrict this to actually 1 -55 you can solve this using run time error handling but wouldnt it be better if we had static checks where upstream we could see an unbounded int being passed into this method and throw a compile error.

<comment><USER22> I think you could do that, but as long as you allow the usual operations on bounded variables (say, multiplication), you would have to ensure that the other operand is also bounded, or else you get an unbounded result nonetheless. Meaning, all variables that are used in any expression would have to be bounded eventually. There's also the problem that the compiler would have to infer that [1-10] - [1-2] can be negative, but does not have to. So with every expression on bounded variables, you increase their bounds' range, likely deleting the system's benefits.

<comment><USER21> I agree its super complex, these bounds wouldn't be limited to integer based variables. I would also argue there are very narrow instances where you would want to bound a variable and also do arithmetic on it. The language should make the bounding optional and unbounded possible.

</comment></comment></comment><comment><USER23> I think rigorous application of formal methods plus deployment techniques like unikernels have the potential to improve the quality of a lot of software.

<comment><USER24> I'm more of a pessimist. If you can't get C programmers to handle memory buffers correctly, how are you going to get them to use actual formal methods or annotations that rely on understanding substantially more math than the average programmer has?

<comment><USER25> Make the infrastructure you run things on provide what appears to be formal methods for interactions, but also make it appear inconsistent over a given regular timeframe. Abusers of the system will find lots of issues with it because it will break unpredictably at random times if they are hammering away. Happy users of the system will having it break every now and again, but will likely avoid making things overly complex as a result of it increasing the chances it will break over a given time period.

Expecting infrastructure to be completely reliable is a fallacy and should be embraced instead of chased.

Suffering on the part of the former "programmer" (hacker) will be paid while obtaining results of various runs to exploit the system from the outside (external). Suffering on the part of the later "programmer" (coder) will be paid internally while working on more efficient solutions.

We'll need to code up the two types of suffering into stores of value, and tie them to cryptocurrencies, but that should be fairly straightforward to implement.

</comment></comment></comment><comment><USER26> You might regard unit tests and formal proof to be opposite ends of the same scale with model driven testing being somewhere in between.

One may be well advised to pick according to what you need. Formally proving the behaviour of your whole web app would likely take you an order of magnitude longer to write.

</comment><comment><USER27> "Beware of bugs in the above code; I have only proved it correct, not tried it." (Donald Knuth)

<comment><USER28> Statement hopefully obviated by seL4 Isabelle to/from C compiler.

</comment></comment><comment><USER29> I think the biggest issue is from a business people perspective, formal requirements needed for this type of development (software development as an engineering discipline) is too slow, and not as open to change as the agile (craft) methods tend to be in software.

<comment><USER30> It depends what business you're in and what your needs are. Agile doesn't get much traction in flight control software or telephone switches.

<comment><USER29> Exactly... anything dealing with critical hardware will/should be done as an engineering discipline wrt development, where tfa's practices could be better. That isn't the majority of software development, which is one-off line of business apps.

</comment></comment></comment><comment><USER3> This is a big win for Haskell, since government contracts and approved vendors tend to have long arcs of doing future business. The idea an EDSL in Haskell was used greases the skids for any future Haskell acceptance on jobs. Good luck!

</comment><comment><USER31> I don't get the idea of a formal method. You're attempting to prevent bugs in code by writing code that describes the final product. In any reasonably complex system the descriptions will be large, complex, and bug prone. How is a "formal method" any better then one of the following:

       - Unit testing: Provide every test case possible
       - Pure Functions: Use small methods that cannot error and always return sane values
       - Fuzzing Testing: To find if the implementation is actually correct or if it is correct by chance

What is the benefit of a formal method? It's just inconceivable for me to see "Hacker-Proof code" and not laugh at whoever wrote this.

<comment><USER32>
        - Unit testing: Provide every test case possible

Even if your program only takes a 32 bit integer as an input you'd have to provide 4294967296 test cases. Most programs' inputs are a bit larger than that.

        - Pure Functions: Use small methods that cannot error and always return sane values

"cannot error" is exactly what formal verification is about. Pureness doesn't prove correctness.

       - Fuzzing Testing: To find if the implementation is actually correct or if it is correct by chance

Fuzz testing is good for finding buffer overflows and such, and those bugs can be ruled out even without formal verification methods (i.e. Rust). Otherwise you'd need to specify every test output possible anyway, and you're back to point 1.

<comment><USER31> > Even if your program only takes a 32 bit integer as an input you'd have to > provide 4294967296 test cases. Most programs' inputs are a bit larger than > that.

How do I go about defining a test using a formal method?

Also, you know as well as I do that you don't need to test every input, only a representative subset if you use unit tests and use a fuzzing testing library.

Using fuzzing, unit testing, pure functions and liberal preconditions through your project in development you'll likely come up with a product that has exactly what you are promising. Add a linter on top of that and for free you've got the safety of healthy paranoia.

Do you have an example of a project that uses "formal methods" so I can see what they are? I'd also like to see something written that has a comprehensive security audit.

Again, from what I'm seeing you're writing code to verify code and calling it "bug proof" just because you've written double the code. That's insanely misguided in my book.

<comment><USER32> > Also, you know as well as I do that you don't need to test every input, only > a representative subset if you use unit tests and use a fuzzing testing > library.

The thing is that you can never be sure that you chose a "representative subset". Unless you test every conceivable input you've verified that your program works for the subset you chose to test, nothing more. For example, how sure are you that your unit tests cover _every_ conceivable edge case?

> How do I go about defining a test using a formal method?

You don't, it's a proof. You don't need tests.

Some links from another comment [0].

I'd also point you to Idris [1] for a friendly dependently typed language if you are interested in learning more.

[0] [https://news.ycombinator.com/item?id=12544477](https://news.ycombinator.com/item?id=12544477)

[1] [http://www.idris-lang.org](http://www.idris-lang.org)

<comment><USER31> > You don't, it's a proof. You don't need tests.

Ok well what does it look like? Can you show me an example of this proof and how it is tested? You can't just say it's proven and remove the need for you to prove you've implemented it correctly. How is the proof validated and how is the source code checked against this?

Also by the act of checking the source code you've essentially just created a test case. So we are back to my initial phrasing.

What I'd like is for someone to show me how I go about proving something. Could you, if possible, walk through "proving" an implementation of a Fahrenheit and Celsius converter or something? What do you do? Where do you start? What does this look like?

That's whats been driving me crazy about all of this "formal methods" thing. People say "it's proven" and when you say "how do you check your code or how do you verify what you did was correct" they say "we made a proof, it's proven". No information is exchanged other then the assertion of "what I did was right".

<comment><USER32> Well, an F to C converter is not a terribly interesting case, because it would be trivial to implement. When you think about it, how would you test this in your favourite language of choice? By computing the expected value by using the _same_ formula you used to compute the value you are testing in the first place.

But here's another example that came up recently. Let's say you want to write a function that takes a string and returns its first character. Now, it would be an error to call this function with an empty string, because then what would it return?

In a normal language, you'd probably check if the string was empty and then return null or something. When testing the function, you'd have to remember the empty string case and write an unit test for it (now I don't know about you, but I can't say I'd always remember to write a test case for this particular edge case; normally I'd forget).

Can we do better? It turns out we can.

We can encode invariants about our program on the _type level_. Types can be more than just strings, ints and chars. They can also be _propositions_ , i.e. statements about our program. In this particular case we can construct a type

        NonEmptyString

that can only be constructed by a function like this (using Haskell syntax):

        neString :: String -> Maybe NonEmptyString

(This means that neString takes a String and returns a Maybe NonEmptyString). But what is this Maybe (also called Option, etc)?

It's like a union type - it can either contain some value, or it must be empty. Now the cool thing about Maybe is that we can't just take out the potential value contained inside it - we have to _pattern match_ on it! What this means is, that whenever you want to see what's inside a Maybe the compiler _forces_ you to tell it what to do in both cases - when there's something inside and when there's nothing inside.

Maybe you can see where this is going. This is how our takeFirstChar function would look like:

        takeFirstChar :: NonEmptyString -> Char

Notice - we say that it only works on NonEmptyStrings! If we try to pass a regular string to it that would be a compiler error. But now we want to read something from the command line and returns it's first char. Let's say we have a read function:

        read :: String

Every time you call this function it gives you a string read from the terminal. Ok, let's put our program together now:

        a = read
        print (takeFirstChar a)

But wait! We can't do that - as I said above, the compiler complains, because we try to pass a String to a function that expects a NonEmptyString. Instead we have to:

        a = read
        case (neString a)
          Just st: print (takeFirstChar st)
          Nothing: print "String was empty"

Notice how we _pattern match_ on the result of (neString a). If the string was empty, we'd match the Nothing clause. In all other cases we'd print the first char.

What we did is _prove_ that the program will behave correctly in all cases - no tests needed! We can't put the program together in any other way, because it would be a type error. In a sense, the fact that the program exists is a proof of its type (programs have types too!)

Now this is a pretty trivial invariant to encode on the type level, but in a dependently typed language you could encode whatever you'd like, i.e. for example that a list is sorted or that a number is the GCD of two other numbers, etc.

This is often not trivial to do, and at some point you start seeing diminishing returns, because the time it takes to rigorously encode a proof is longer than any possible return of investment caused by proving that there are no bugs. But doesn't have to be an either-or situation. You can encode as much invariants as you'd want in your code. I think Haskell strikes a good balance in that regard, although Idris is a very interesting language too.

(Sorry for typos, errors etc, didn't proofread).

<comment><USER31> > But here's another example that came up recently. Let's say you want to > write a function that takes a string and returns its first character. Now, > it would be an error to call this function with an empty string, because > then what would it return?

This is wrong because it depends on the language. The behavior depends on the implementation but if you are meant to return the first character in the string and the string has no characters then you should return an empty string if provided a string with no characters.

From there, if given null you should return null back or throw an exception depending on the language.

My function would, abstractly, look:

      function get_first_letter(s):
        if s == null:
          return null
        if s == "":
          return ""
        return s[0]

      value = get_first_letter(read_string())

      switch (value):
        case null:
          print("No string entered")
          return
        default:
          print(value)
          return

Is this code "proven" just because it handles a every case? What makes this a proof or proven? This is basically just good practice: handle every case that a function can create. This is something that we have all been doing. Why makes a formal method "proven" or different.

> What we did is prove that the program will behave correctly in all cases - > no tests needed! We can't put the program together in any other way, because > it would be a type error. In a sense, the fact that the program exists is a > proof of its type (programs have types too!)

This seems no different from any other language. You've just spread the code you had to write over "neString" and "takeFirstCharacter" and created a new type for it. Why couldn't you have just used the underlying functionality of String to make those checks when needed? For instance, "neString" must be using some sort of string method to check if a String is a NotEmptyString. Why not just put that code where it needs to be?

This just seems like a way to force your hand into using More types that have the same underlying implementation and I just see that as a way to confuse someone trying to come work on your project. When I look at source and say "wait a minute they have 10 types defined for strings and all they do is something that String could do beforehand" I'm a little irked. What makes the implementation that you have created "proven"? Just that the compiler said that all of the types line up? That doesn't make you any safer then before.

If you even make a single cast, a single unsafe block, or anything then you need to test the entire system. Your house of type-verifying cards falls down once you hit even the smallest section of unverifiable code. Just by making types for every one of your billion special cases doesn't mean that you don't need to test the code.

For instance in rust the standard library uses unsafe{} blocks often. This means that any code that goes into or comes out of that block is unverifiable for type. Just by using defined types to create it doesn't make it so the programmer has correctly implemented anything.

Also, you are assuming the implementation of neString is correct. What if that has a bug? Again, just because your passing your data around the correct way doesn't mean the correct things are happening with it.

You can't just make more types and call it all good.

<comment><USER32> > This is wrong because it depends on the language. The behavior depends on > the implementation but if you are meant to return the first character in the > string and the string has no characters then you should return an empty > string if provided a string with no characters.

How? The type is:

        takeFirstChar :: String -> Char

There's no such thing as an empty char. Your get_first_letter essentially has the type:

        get_first_letter :: Either Null String -> Either Null String

Which doesn't guarantee anything and is arguably a lot worse than just:

        get_first_letter :: NonEmptyString -> Char

This is why you can't have proven code in a lot of languages, because they permit you to lie about the actual types. From there, any proof is invalid because it is based on invalid propositions.

Dependently typed and other languages do not allow you to lie about the types (for example, a value can't be null unless this is reflected in the type; you can't throw exceptions or do IO unless this is reflected in the type, etc), hence a well typed program in such a language is a valid proof. You can not implicitly cast between types, i.e. a function like:

        cast :: a -> b

doesn't exist.

A function like print actually has the type:

        print :: String -> IO ()

Which tells you that it is doing IO. You can't call such a function from a pure function for example, the types wouldn't permit it.

> Also, you are assuming the implementation of neString is correct. What if > that has a bug? Again, just because your passing your data around the > correct way doesn't mean the correct things are happening with it.

I was simplifying, but neString would actually have a type similar to:

        neString :: String n -> Maybe (String (n != 0))

where n is the length of the string. Notice, the length is encoded in the type! A wrong implementation (one that returns i.e. Maybe (String 0)) will not type check.

But yes, you can have errors in your proof, no doubt. But these are specification errors, which there's no way to get around. What a proof guarantees is that there are no errors in the _implementation_ of your specification.

<comment><USER31> Ok so if you are given a specification and you use formal methods throughout and it doesn't conform to the specification you were provided with at the end you have made an error. The specification is not at fault here. What you are doing is claiming types into and out of functions decide if they are functioning correctly. This is not the case at all.

I think that most bugs aren't because the type you were expecting was wrong but the data produced by a function was wrong.

Implementations cannot be judged just because they accept the correct types.

For instance, if I am told to write a function to predict lottery numbers and do the following

       LoteryNumberType
       get_lottery_number :: LotteryNumberType

If I call `get_lottery_number` by your logic it will always provide me with the real winning lottery number since the types check out. That is absolutely incorrect. Types can't prove functionality. They do provide protection from a set of bugs but those bugs are also avoided easily by handling every case that a function can return which was already being done before formal methods where an idea.

You can't say a program will have no bugs because the types check out. Is that what you are saying? Your code's types match in all uses -> this means there are no bugs -> this means I don't need to test my code?

Is that really what you think?

<comment><USER32> > What you are doing is claiming types into and out of functions decide if > they are functioning correctly. This is not the case at all.

When I say proof, I mean it in the mathematical sense. The Curry–Howard isomorphism [0] formalizes the relationship between (mathematical) logic and type theory. Unless you are saying mathematical logic is inconsistent (and thus every mathematical proof is invalid) this is absolutely the case.

The same way you can construct a mathematical proof that e.g. n is prime, you can can construct a type Prime n that proves that n is prime [1].

> I think that most bugs aren't because the type you were expecting was wrong > but the data produced by a function was wrong.

This is where your misunderstanding stems from. Continuing with the example from above, if you have a function:

        makePrime :: n -> Prime n

the function _can not_ construct (Prime n) if n is not a prime.

> If I call `get_lottery_number` by your logic it will always provide me with > the real winning lottery number since the types check out. That is > absolutely incorrect. Types can't prove functionality.

If you give me a specification that constructs predicted lottery numbers I could absolutely turn it into a type :)

> They do provide protection from a set of bugs but those bugs are also > avoided easily by handling every case

But you don't have proof that you are handling every case :)

> You can't say a program will have no bugs because the types check out. Is > that what you are saying?

Yes, if the types correspond to the specification then there are no bugs. The specification can still have bugs though, but that's unavoidable. The thing is that you've proven the program does what you told it to do.

Once you stop thinking about types in the Java sense and start thinking about them as logical propositions it will all make sense. I provided you with a couple of links in the other comments and here if you are still interested.

[0] [https://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspon...](https://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence)

[1] [https://github.com/agda/agda- stdlib/blob/master/src/Data/Nat...](https://github.com/agda/agda- stdlib/blob/master/src/Data/Nat/Primality.agda)

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER33> Here are my questions (to anybody with knowledge of this field):

\- Is this type of programming related to the functional-programming field?

\- How is this different to OOP/imperative code?

\- What language(s) will be used to write code for this?

<comment><USER28> I can speak about Isabelle/HOL specifically only.

1) functional programming is a subset of mathematical proofs. Isabelle syntax is somewhat similar to what is offered in ML family of functional languages. Unlike functional languages, you can use more advanced constructs than bijections (can model superposition etc.) and it is easier to state things over sets.

2) imperative code is a subset to this too with added order of operations. Language is somewhat different though Isabelle has a module that has necessary proofs to verify imperative programs.

</comment></comment><comment><USER34> Just thinking out loud: if a program can check the correctness of another program against a formal spec, can't it just _write_ the checked program from the spec?

<comment><USER20> As others have already replied, sometimes it can. But sometimes, and particularly if we care about efficiency, this is so difficult that we're not even close to being able to automate it.

For example, here is my "formal definition" of a primality checker:

IsPrime(Int n) = n > 1 and not(exists a, b in Int: a > 1 and b > 1 and a * b == n)

It is not directly executable, because it uses the "exists" quantifier over all integers. A clever code extractor should be able to somehow convert this to a finite computation. But would it be able to come up with the polynomial- time AKS primality test? [1] I highly doubt it.

Unless, of course, there is a special case for recognizing this particular definition. But I don't think that really counts, because I'm only using primality checking as an example. You can't have a special case for everything.

[1] [https://en.wikipedia.org/wiki/AKS_primality_test](https://en.wikipedia.org/wiki/AKS_primality_test)

<comment><USER28> Actually, Isabelle has methods that check isomorphism of proofs in a brute force way. It is pretty slow, so it is almost always better to just say what specific proof you want to use.

</comment></comment></comment><comment><USER35> All we need now is a proof that the proof program is correct. And a proof that the proof proving program is correct.

<comment><USER28> Internal consistency is relatively easy to verify. Completeness to some extent as well.

The manual task is to verify all the assumptions.

</comment></comment><comment><USER36> I don't understand this.

In order to use formal verification you have to provide a complete and correct specification of what you want the software to do. We already have formal languages for doing this called programming languages.

How is this any different from a programming language?

<comment><USER37> Programming languages have to be (efficiently) executable, specifications can be logical/declarative. E.g. in a specification I can state things like "forall functions, with uncomputable property foo, we have bar". Plenty of things are uncomputable (e.g. quantifiers over natural numbers), but useful in specifications.

There are good and bad specifications, same as for programs. For the semantics of a programming language you could essentially transcribe an interpreter in the form of a structural operational semantics and these are relatively error prone. Instead, you could give an axiomatic semantics, which is a lot more high-level. An equivalence proof between the two gives you a high level of assurance that the operational interpretation you had in mind while writing your interpreter actually means what you think it means.

A recent example, the formal specification of the weak memory model of C11 turned out to be wrong (in the sense that it forbids common compiler optimizations, because programs have access to a time machine), but this was discovered when trying to develop a program logic for C11.

In practice, most broken specifications I have seen were written by people who never really worked in formal verification. I am not aware of a single instance where a piece of formally verified code was broken because of a broken specification. There are cases where the specification had to be extended. E.g. CompCert was initially developed as a whole program compiler and the spec had to be extended for separate compilation. This broke the alias analysis.

</comment></comment><comment><USER38> To save others time. I've copied some of the biggest points of the article. My comments are in [brackets], except these^^ first few sentences.

"Between the lines it takes to write both the specification and the extra annotations needed to help the programming software reason about the code, a program that includes its formal verification information can be five times as long as a traditional program that was written to achieve the same end."

"Jeannette Wing, corporate vice president at Microsoft Research. "Any natural language is inherently ambiguous. In a formal specification you're writing down a precise specification based on mathematics to explain what it is you want the program to do.""

""We're not claiming we're going to prove an entire system is correct, 100 percent reliable in every bit, down to the circuit level," Wing said. "That's ridiculous to make those claims. We are much more clear about what we can and cannot do.""

[In the experiment the article is mostly based on] "The hackers were mathematically guaranteed to get stuck. "They proved in a machine-checked way that the Red Team would not be able to break out of the partition, so it's not surprising" that they couldn't, Fisher said. "It's consistent with the theorem, but it's good to check.""

"In a return to the spirit that animated early verification efforts in the 1970s, the DeepSpec collaboration led by Appel (who also worked on HACMS) is attempting to build a fully verified end-to-end system like a web server. If successful, the effort, which is funded by a $10 million grant from the National Science Foundation, would stitch together many of the smaller-scale verification successes of the last decade. Researchers have built a number of provably secure components, such as the core, or kernel, of an operating system. "What hadn't been done, and is the challenge DeepSpec is focusing on, is how to connect those components together at specification interfaces," Appel said."

<comment><USER39> "Jeannette Wing, corporate vice president at Microsoft Research. "Any natural language is inherently ambiguous."

Lojban (nee Loglan) is a conlang designed to be syntactically unambiguous but as usable in speech and thought as a natural language [https://en.m.wikipedia.org/wiki/Lojban_grammar](https://en.m.wikipedia.org/wiki/Lojban_grammar)

</comment></comment><comment><USER40> Such 'hacker-proof code' can only be as secure as the underlying hardware. If such a cure already existed, we wouldn't be subjected to the current hacking/phishing epidemic.

"these malfunctions could be as simple as a buffer overflow"

No amount of 'formal verification' will detect or prevent buffer overflows, which are a defect in how the hardware allocates memory. The cure must also be found in the hardware.

"Back in the 20th century, if a program had a bug, that was bad, the program might crash, so be it,"

It must of been on a different planet, cause I can remember using networked computers in college way back in 1984. and the first Internet worm occurred in 1988.

<comment><USER41> Hardware bugs are NOT the major source of widely-exploited vulnerabilities in practice. They're a tiny fraction of exploits being used in the wild, and certainly of the ones being used to target the general population.

Further, a buffer overflow is absolutely not a defect in how hardware allocates memory. It's a logical flaw in the software that reads/writes beyond the limits of the memory the programmer intended to access.

<comment><USER42> It's also worth noting that some critical hardware components (e.g. CPUs since the infamous division bug) are formally verified as well, so manufacturing defects should be the largest concern for them.

<comment><USER28> Only a tiny fraction of the CPU is formally verified. There are frequent errata. And plenty of undefined behaviour as well as races you can hit if you really try.

</comment></comment></comment></comment><comment><USER43> This article was just wildly misleading, the title is well, it speaks for itself.

Interesting language and rather than 'formally proven' as the article wildly claims it is a strongly typed system ala Haskell. So yep looks a great idea for secure systems - but formally proven - bah! :-)

Has anyone here actually formally proved a non trivial program, say a couple of hundred lines on NCSS?

How about tens of thousands, hundreds of thousands or millions of lines of code. The complexity of the proof would be insanely complicated such that the level of expertise to define the requirements would be (if at all within the limits of human endeavour) only for maybe a handful of people. And do those people make good business analysts, or hackers, or entrepreneurs or even just communicators.

Jeez the misinformation that gets spread!

<comment><USER44> > Has anyone here actually formally proved a non trivial program, say a couple > of hundred lines on NCSS?

I don't know what NCSS is, so am going to answer as if your sentence stopped two words earlier.

How about the CompCert C compiler [1]? Or CakeML [2]?

And let's not forget seL4 [3], which has a formal proof that the implementation in C conforms to the specification, and a further formal proof that the binary code is a correct translation of the C code.

[1] [http://compcert.inria.fr/compcert-C.html](http://compcert.inria.fr/compcert-C.html)

[2] [https://cakeml.org](https://cakeml.org)

[3] [https://sel4.systems](https://sel4.systems)</comment></comment>


How Expedia finds Flights - <AUTHOR> https://techblog.expedia.com/2016/03/07/how-expedia-finds-flights-a-detailed-view/ <comment><AUTHOR> Hi HN,

I work for Expedia, so happy to answer any questions on how things work or dispel any myths. Ask away.</comment>


Job interview theory - <AUTHOR> http://www.scottberkun.com/blog/2010/the-winchester-job-interview-theory/ <comment><USER2> This theory is actually well documented in academic HR circles.

</comment><comment><USER3> "We never go back a year later and evaluate" I hope this isn't 100% true, I know we re-evaluate our interview impressions after we've hired someone.

Finding out how well the guy you didn't hire is doing would be an awesome service. It's hard to keep tabs on them all.</comment>


Ask HN: Would you discuss your company's analytics privately? - <AUTHOR> I do a lot of analytics, mostly in SQL/Python, across, at the moment, 5 tech companies. 50-80% of this is repeatable. The other 20% is not. And that is the stuff I feel that actually could make companies significant money.
Do you have the same feeling? Would you share your analytics (the HOW and the WHY) privately in exchange for other experts in the field sharing their knowhow?
Asking because I am contemplating whether to start a private community - somewhere I would not be afraid of an end consumer finding how we do analytics. <comment><USER2> I just got an unsolicited email asking me to comment in this thread.

<comment><USER3> Me too. But since we're here I'd give it a try. I think the idea is worth developing.

</comment></comment><comment><USER4> The stuff I'm doing is rather straightforward user retention like ARPU, ARPPU, LTV, day-2 retention, etc. There's no special sauce. So, I wouldn't mind sharing that, but I fail to see what kind of special analytics could be used that users would be concerned about? Got any example?

</comment><comment><USER5> I think it depends on the industry. Doing analytics that about UX and if people are enjoying using a site (the type of stuff I'm interested in) is very different than sort of greyhat SEO/referral marketing type stuff.</comment>


Read a job application from Steve Jobs from 3 years before he cofounded Apple - <AUTHOR> http://www.businessinsider.com/steve-jobs-job-application-3-years-before-apple-auction-2018-3?lipi=urn%3Ali%3Apage%3Ad_flagship3_feed%3BBx%2B8vsh8RDWBJMBVPM5c2g%3D%3D&licu=urn%3Ali%3Acontrol%3Ad_flagship3_feed-object <comment><USER2> His handwriting prior to calligraphy training sucked.</comment>


Best GitHub repositories - <AUTHOR> https://github.com/josephyzhou/github-trending

<comment><USER2> Why push a new document every day instead of simply updating the document? This is git, it's easy to track changes...

<comment><USER3> Because perhaps someone wants to look at trends over time. Doing it this way means that you don't have to scour through the git history to get your data. Also, scouring the git history, as you suggest, assumes that each commit corresponds to exactly one daily update. What if there are commits that fix typos or other errors? How do you programmatically skip over those?

Pushing a new document every day is the correct choice here.

<comment><USER4> No, the correct choice would be using one file and tags for each date. To fix a typo you just go to appropriate tag and make a commit.

<comment><USER5> "correct" w.r.t. what ? A checkout (or a tarball as offered by GitHub) of the repo is all those files, which is probably what most people want.

</comment></comment></comment></comment><comment><USER6> For me personally both objective c and go are not that interesting, so I find [http://www.coolgithubprojects.com/](http://www.coolgithubprojects.com/) more useful.

<comment><USER7> That looks pretty good. Is there a way to filter by language, or can you just order by language?

And it'd be good if he got rid of the greengrocer's apostrophes[1].

[1] [http://en.wiktionary.org/wiki/greengrocer%27s_apostrophe](http://en.wiktionary.org/wiki/greengrocer%27s_apostrophe)

<comment><USER6> Right now you cannot filter, but this is something the author said to be working on. You can see the discussion on Reddit here [http://www.reddit.com/r/coolgithubprojects/comments/2b9vph/r...](http://www.reddit.com/r/coolgithubprojects/comments/2b9vph/rcoolgithubprojectss_new_daily_aggregator_website/)

</comment></comment></comment><comment><USER8> This is the trending GitHub repositories for javascript, objc and go. I would expect also for C/C++, Java, Ruby, Python and others.

</comment><comment><USER9> "Best" == "trending" ???

<comment><USER10> Even in README they wrote "most popular", not "best". Justin Bieber is also popular...

<comment><USER6> Also thought of Justin Bieber as a good example of popularity != quality.

</comment></comment></comment><comment><USER11> You should use directories for hierarchy instead of a very long unwieldy list.

Try 2014->08->2014-08-06.md

</comment><comment><USER12> That's nice.

Is there anything like freshmeat that would show new releases?</comment>


Show HN: Yarr – Yet Another RSS Reader - <AUTHOR> https://github.com/nkanaev/yarr <comment><USER2> At least a screenshot is there but maybe provide a bit more details.. I really don't get why people show off projects with zero description. Sure it's an rss reader but what features does it actually offer?

E.g. I see "make build_macos" and wonder if other platforms are supported? I don't want to have to find out myself that it does not support linux.

<comment><AUTHOR> author here.

Since it's yet another RSS reader, it supports the basic functionality of almost all the other alternatives (managing feeds, reading, importing/exporting, searching etc.).

The plans are to support all 3 platforms (Linux, Windows, MacOS). You can try compiling it via `make build_linux` & `make build_windows` on the corresponding platforms.

<comment><USER3> I, too, would have appreciated slightly more documentation. Here are two questions I had, and what I figured out.

Many RSS readers are stand-alone GUI applications. I would have appreciated an up-front notice that this is a hosted solution. (Which is what I am looking for. I'd like the same view of what's read and unread on my different devices, thank you)

Different RSS readers use different storage backends. I dug through your code, and it seems to use SQLite, which is exactly what I hoped for. It's a huge difference in deployment and system administration headaches whether it uses an embedded or a hosted database.

Looks interesting! I'd also appreciate a prebuilt binary for Linux, but I understand that it's still early days. Paying attention :)

<comment><AUTHOR> thanks for the feedback. i'll update the readme to reflect that.

</comment></comment></comment></comment><comment><USER4> Should have waited with launch until Saturday: [https://en.wikipedia.org/wiki/International_Talk_Like_a_Pira...](https://en.wikipedia.org/wiki/International_Talk_Like_a_Pirate_Day)

<comment><USER5> Why?

<comment><USER6> Saturday = int'l talk like a pirate day (as linked by GP).

Pirates say, "Yarr!"

</comment></comment></comment><comment><USER7> Glad to see people still making new ways to absorb via rss - I still feel it's the best method for getting news and things, and the more options we have to show others how they can be used - maybe the better.

Wonder if anyone has made a self-hosted way to create a 'my.yahoo' or netvibes , pageflakes kind of page with rss feeds?

I started to put together some plugins for wordpress/buddpress to allow people to make something like that for their own, but got bogged down and never tried to mash it all together yet.

Anyone have a browser extension that can find rss feeds for pages?

I long for the days of yesteryears where yahoo news searches had an rss button or link to copy right there - and discovering rss on news portals and elsewhere was easier not hidden.

<comment><USER8> > Anyone have a browser extension that can find rss feeds for pages?

I was looking for something like that for a long time after all the browsers kinda removed that functionality. I'm not using the following for Safari and it's great:

[https://rss-extension.bitpiston.com](https://rss-extension.bitpiston.com)

<comment><USER9> > Anyone have a browser extension that can find rss feeds for pages?

I wrote/use this greasemonkey script - [https://greasyfork.org/en/scripts/6261-rss-atom-feed- subscri...](https://greasyfork.org/en/scripts/6261-rss-atom-feed-subscribe- button-generator) \- it still mostly works but strict CSP on sites these days has been causing some trouble. Maybe turning it into a browser extension is the thing to do.

</comment></comment></comment><comment><USER8> Always great to see more RSS readers. Are you thinking about making it API compatible with others so people can use any of the existing apps?

I'm currently using [https://github.com/miniflux/miniflux](https://github.com/miniflux/miniflux) (Also written in Go) and it supports the Fever API which means I can use any app on most platforms to sync with.

<comment><USER10> This is probably a dumb question, but what does the Fever API do that isn't done in RSS itself? Does it keep track of what you've read already?

<comment><USER8> Not a dumb question. It syncs read status across their web interface and every Fever supporting app on all platforms. You can also "star" items which then also gets synced.

</comment></comment></comment><comment><USER11> I really like the minimalist UI! I'm excited to try this out. I'm the author of the gofeed[0] dependency and it is cool to see people using it.

[0] [https://github.com/mmcdole/gofeed](https://github.com/mmcdole/gofeed)

<comment><USER8> Thanks for that library, I use it in some of my projects too.

</comment></comment><comment><USER12> This reminds me a lot of an older iteration of Feedbin: [https://github.com/feedbin/feedbin](https://github.com/feedbin/feedbin)

</comment><comment><USER13> Haven't tried it but it looks nice. Reminds me of [https://bazqux.com/](https://bazqux.com/)

</comment><comment><USER14> _" Yarr"_ name already used by other project.[0]

[0] [https://github.com/Yarr/Yarr](https://github.com/Yarr/Yarr)

<comment><USER15> There are so many projects out there, it's hard to avoid naming collisions. I don't think a project with 10 stars can lay exclusive claim to a four letter name.

<comment><USER16> There are already many RSS readers with this name:

[https://github.com/channikhabra/yarr](https://github.com/channikhabra/yarr)

[https://fossdroid.com/a/yarr.html](https://fossdroid.com/a/yarr.html)

etc. The name sounded familiar (I think I used one in the past) so I googled and I haven't found it, but I did find many others.

<comment><USER17> The clue is in the "ya" ... "yet another"</comment></comment></comment></comment>


Ask HN: Is there codegen framework for business logic? - <AUTHOR> I have been working on a big project for quite some time now and I am finding myself rewriting and optimizing/duplicating the code quite often and not finishing the damn thing as a whole(this is not just the programmer's strive for perfection but the mostly sheer size of the project). And I am getting really tired of writing the same stuff over and over again. I work with Go which does not have generics but I would not say that is the issue here(I actually do not miss generics, maybe once or twice a year tbh).
In essence, over the years, I grew tired of writing so much code. It's not that I do no like writing code, it's just that I clearly see how much code I need to write in order to implement the business logic. And I'm just tired of it.
So I want to create a code generator that would take my business logic and generate the full implementation out of it so I can truly focus only on that and not the code itself. I have wrote code generators before, usually for event-sourcing stuff and repositories(db), so this is nothing new. But I am after more abstraction, less time spent writing code, more time spend developing the application as a whole. Imagine something like terraform but not for infrastructure but for the code.
So before I attempt to write something on this scale I was wondering if maybe there already is something out there? <comment><USER2> It's a holy grail. Like quite a few advanced technologies there is a gap between something the creator of the system finds comfortable to work with and something that other people can pick up and that is one reason why this tech hasn't diffused.

What do you think about tools like

[http://www.clara-rules.org/](http://www.clara-rules.org/)

or

[https://www.drools.org/](https://www.drools.org/)

?

<comment><AUTHOR> thanks for the links. the clara rules gives me some ideas.

</comment></comment><comment><USER3> I feel the same problem! I've been writing web apps in various technologies (from backbone to react, php to Node) and always felt I had to reimplement the same common features (while using a lot of code + tests, ...).

Thinking similarly as you (terraform for code), together with my brother I started working on [https://wasp-lang.dev/](https://wasp-lang.dev/) \- it is a DSL for building full-stack web apps. We are still very early but have some initial functionality.

Would love to hear if that resonates with what you had in mind.

We also did a quite extensive research of other solutions so happy to share what we discovered here as well.

E.g. From the purely code-generators:

[https://divjoy.com/](https://divjoy.com/) \- generates react code

[https://bullettrain.co/](https://bullettrain.co/) \- Ruby on Rails starter

<comment><USER4> This looks great, even though it is new it looks polished. I am not a web developer but would like to be able to create web interfaces for APIs and other small projects I've built. This seems like it would be a great tool for things like that. Keep up the good work!

<comment><USER3> Thank you very much! That definitely sounds like the good use case. If you'd like to support us feel free to star our repo at [https://github.com/wasp- lang/wasp](https://github.com/wasp-lang/wasp), that is currently the best way for us to show that other people are excited about Wasp too :).

</comment></comment></comment><comment><USER5> Workflow engines might be worth considering. Options from the Microsoft world include PowerApps, BizTalk and (historically) Windows Workflow Foundation.</comment>


Why Constant-Time Crypto? - <AUTHOR> https://www.bearssl.org/constanttime.html <comment><USER2> From having spent a bunch of time working on wrapping crypto libraries for Python, the author's name (Thomas Pornin) is one that I regularly saw providing in-depth answers on the Cryptography stack exchange: [https://crypto.stackexchange.com/users/28/thomas- pornin](https://crypto.stackexchange.com/users/28/thomas-pornin).

It is encouraging to see BearSSL at beta stage. I believe the last time I saw it, Thomas still considered it to be alpha. The promise of a small, MIT- licensed crypto library, written by a solid cryptographer who understands implementation details is nice. I've used libtomcrypt in the past, but as a non-expert, I've always wondered how resilient and well-written the code base is.

<comment><USER3> libtomcrypt was started by Tom St Denis as he was learning programming, at the age of 15 years old or so. The exact history could be extracted by reading the Usenet sci.crypt group archives. In its early days suffered the horrible security woes that you can expect with these premises (e.g. [https://groups.google.com/d/msg/sci.crypt/j3EW_pt6pKA/u8PYkf...](https://groups.google.com/d/msg/sci.crypt/j3EW_pt6pKA/u8PYkfAkvL4J)). To his credit, Tom St Denis was always very honest and prompt to fix the issues. Pretty recently, it still had very bad issues (e.g. [https://github.com/libtom/libtomcrypt/issues/74](https://github.com/libtom/libtomcrypt/issues/74))

I got no idea what to expect now, but I've never seen it used in anything I'd consider serious. To many people, it's forever tainted. The lack of CVE in libtomcrypt is not an indication of quality, just and indication of lack of usage. In any case, its lack of support for PKCS#11 means it's not suitable for use cases where keys must be securely stored.

</comment></comment><comment><USER4> Looks like @pornin has invested a lot more effort since BearSSL's initial release nearly a year ago, previous HN comments at:

[https://news.ycombinator.com/item?id=12863699](https://news.ycombinator.com/item?id=12863699)

</comment><comment><USER5> A little off-topic, but I wonder if the barcode-ish design in the header is a puzzle with an interesting hidden message. It's not uncommon for cryptographers to do things like this.

<comment><USER6> it's 3 of 9 barcode ([https://en.wikipedia.org/wiki/Code_39](https://en.wikipedia.org/wiki/Code_39)) that says "BearSSL"

</comment></comment><comment><USER7> > Curve25519 allows for much simpler code (for instance, there is no need for > validation, since all sequences of 32 bytes are by definition valid), and > the "natural" Montgomery ladder is constant-time.

It's worth noting that no validation is strictly necessary, but some iinputs can force the output to be all-0[1]. That _should_ be checked.

[1] RFC 7748 ([https://www.ietf.org/rfc/rfc7748.txt](https://www.ietf.org/rfc/rfc7748.txt)), p. 14

</comment><comment><USER8> It would only matter to cryptographic code if an implementation somehow used floating-point, but the source-level conversion from floating-point to unsigned integer can also leak information in execution time when translated to x86 code:

[https://godbolt.org/g/LqUDir](https://godbolt.org/g/LqUDir)

Other implementations purely in hardware or purely in software would be constant-time, but the x86, only offering an instruction for the conversion to signed integer, leads to a mixed solution in which the short sequence of instructions generated by compilers contains a conditional branch on the value being converted.

</comment><comment><USER9> I had another idea for making constant time programs. The idea is that you create a virtual machine without loops or branch instructions, in which each instruction is tested so that the amount of time it takes is independent of the instruction's input or output. You then compile your C code to this instruction set, and execute it on the VM. A program running on this VM, no matter how it's produced, will execute for the same amount of time.

Why not do this for crypto?

<comment><USER10> I'd do it the other way round. A VM is a bit of a pain and you can't target a constant-time-only VM with a regular C compiler. Instead I'd produce a restricted C compiler that only accepted constant time programs, and mapped directly to a limited set of machine instructions. Regardless of what you do, you'd have to produce a whilelist of constant-time machine instructions, so you might as well emit them directly rather than relying on a general purpose optimising compiler to do the right thing.

You can then emit an object file containing the functions you're interested in and link it to the rest of your non-constant-time program.

<comment><USER11> "Instead I'd produce a restricted C compiler that only accepted constant time programs, and mapped directly to a limited set of machine instructions."

This has more potential just because it could be licensed in embedded sector to reduce work on things such as WCET analysis for hard-real-time. That money and uptake can feed back into the compiler's development for things such as constant-time-preserving optimizations. I haven't seen one of these, though. They typically do timing analysis manually (i.e. specific tool) since they have to assess the algorithms themselves, interactions with other components, and so on. Neatest thing I found looking into that was a formally-verified WCET analyses that was built on top of CompCert compiler.

Oh wait, just found something:

[https://cseweb.ucsd.edu/~dstefan/pubs/cauligi:2017:fact.pdf](https://cseweb.ucsd.edu/~dstefan/pubs/cauligi:2017:fact.pdf)

</comment></comment></comment><comment><USER12> Silly question here: why not get a reasonable worst-case time measure one-off, then yield the thread until total time elapsed for said crypto op is up?

<comment><USER13> First of all: that technique is not very accurate, calling sleep() is not guaranteed to return in a specific amount of time.

But more importantly, that only covers the basic timing attack side channel and not even that very well. Cache and branch predictor attacks are still possible (and these are a bigger threat when you're using a virtual machine that may be shared with your adversary). Not to mention all the side channels (power consumption, etc) that are visible if your hardware is compromised.

And if you do end up yielding a thread, the context switch overhead will be measurable. It can take hundreds of microseconds to fully recover from a context switch (TLBs and cache misses, etc), which will certainly affect the timing. It would almost certainly be possible to detect if the encryption method yielded the thread or not based on timing alone (e.g. encrypting next block would consume more time after a thread yield).

There are no easy ways out, crypto code should be free of side channels: constant time, no data dependent memory accesses (cache attack), no data dependent branches (branch predictor attack), etc. This requires the crypto implementor not only to be proficient in the mathematics of cryptography but also details of the computer architecture they're running on.

</comment></comment><comment><USER14> Something I really dislike about OpenSSL is how many generated header files it requires. Does BearSSL manage to implement everything in standard C?

<comment><USER15> What is everything? The TLS and X509 code is implemented in forth compiled to C.</comment></comment>


BMW speeds up plans to electrify 25 new models, now due by 2023 - <AUTHOR> https://arstechnica.com/cars/2019/06/bmw-speeds-up-plans-to-electrify-25-new-models-now-due-by-2023/ <comment><USER2> I'm surprised we don't see more plugin hybrids on the market, they seem to offer most of the benefits of full electric without the downsides. At least if most of your journeys are reasonably short.

<comment><USER3> Could you elaborate on the downsides of fully electric vehicles?

Just interested, from my perspective the only major downside would be cost, and it wouldn't take much, either in additional taxation on buying/running ICE cars, or just more mass production of EVs, to rectify that, at least if you compare like for like (new EV vs. new ICE).

It'll take a long time to attack the 15 year old Japanese banger market (I've had cars that cost literally 100-200 quid a year to run, all costs included except fuel), sure.

<comment><USER2> Cost, range, availability.

<comment><USER3> Range is a solved problem. Modern EVs get over 300 miles and charge 150 miles in 15-30mins.

I'm not sure what you mean by 'availability' \- in the context of your comment "I'm surprised we don't see more plugin hybrids on the market", wherein we're talking about what car manufacturers could be doing, well, they're all available.

A Model X with a Land Rover shell is obviously feasible, it's just that no-one has done it yet. It's probably within the means of a dedicated enthusiast.

I'm surprised that car manufacturers are dragging their feet. ICE's are absolutely dead technology.

<comment><USER2> Range is only a solved problem if you spend a lot of money.

Availability is an issue, most EVs in the UK are on 12 month lead times. Volkswagen have actually withdrawn some cars from sale.

<comment><USER3> I think we're just talking past each other here, I don't disagree.

I just think this all boils down to cost. The lower cost cars are crap or unavailable.</comment></comment></comment></comment></comment></comment>


Men Are Better at Maps Until Women Take This Course - <AUTHOR> http://nautil.us/issue/54/the-unspoken/men-are-better-at-maps-until-women-take-this-course-rp <comment><USER2> Bad URL (redirects to nautil.us home page). The correct URL seems to be:

[http://nautil.us/issue/32/space/men-are-better-at-maps- until...](http://nautil.us/issue/32/space/men-are-better-at-maps-until-women- take-this-course)</comment>


Is anybody still looking for Python jobs? CACI has openings in Washington, DC. - <AUTHOR>

<comment><AUTHOR> you can apply on our website www.caci.com, job number 53189</comment>


SeaStar – high performance C++ framework on top of Linux or OSv - <AUTHOR> http://www.seastar-project.org/

<comment><AUTHOR> Built by the same people who built OSv. They achieve twice the throughput of standard memcache with their own memcache implementation (built on SeaStar), as well as nearly perfect scaling to multiple CPUs while still using a multithreaded model.</comment>


Ask HN: Licensing concerns for work - <AUTHOR> In previous companies, I've signed IP agreements that basically said, "you code it? we own it. all of it"
I really don't like those kinds of agreements, but I understand them.
Now that I'm running my own company, and doing coding for infrastructure, I realize there's a need to formalize things a bit more, especially as I take on help.
I can completely understand $CUSTOMER wanting to keep code for a proprietary product in-house and private. Absolutely no objections there, whatsoever.
But what if you learn some cool technique while you're doing code, and you want to be able to reuse that later (and it has nothing to do with a customer's product specifically)
Is there some kind of licensing arrangement that covers that, so that learning and sharing of knowledge can still happen, but IP is protected? <comment><USER2> IP agreements generally cover the work product you create and not general programming techniques and concepts that you learn. This is different from if you come up with something patentable via your work which your employer usually owns.

That said I have a lawyer edit my IP agreements to scope them as tightly as possible to the company, instead of signing the broad "we own everything you make even outside of work". For some reason most devs seem to just sign them without realizing they have a say in the matter.

In my contracting work my lawyer added a clause about things that I create in the process to make my job easier so that no client owns those. There's a technical term for this but it's slipping my mind right now. It covers things like writing your own code generators and automation scripts that you might use with multiple clients but are not a part of the work product.

</comment><comment><USER3> I would tell the customer if they ask, which they won't, that I invented the cool technique earlier and that I'm just re-using it.

</comment><comment><USER4> dazfuller is correct in that you cannot conflate IP and copyright. Copyright protection is a certain type of IP protection that can be afforded to certain types of tangible creative works. But "IP" is a much broader concept than just copyright.

There's a lot of focus in the law about core types of IP that are protected by statute: copyright, trademark, patent.

It is quite possible that the type of cool technique you develop while doing code for a customer wouldn't be protected by copyright, trademark, or patent law. But most customers probably want you to enter into a contract that governs ownership of IP.

By contract, you can protect certain types of IP that, for example, wouldn't be subject to copyright protection. Depending on what is in your contract with your customer, you may end of inadvertently winding up with your customer "owning" any technique, idea, know-how, etc...that you come up with in the course of performing services with the customer. ("Owning" this type of IP is not the same as "owning" certain other types of IP, as concerns 3rd parties. But that's not particularly important for your question.)

Even if the customer couldn't sue you for copyright infringement for using a technique they end up "owning" by contract, they might be able to sue you for breach of contract or trade secret misappropriation, depending on how you use the technique and its value proposition to the customer. Or, if the technique is patentable, they might be able to apply for a patent covering the technique and prevent you from using the technique that way.

There are a number of ways to work around this in your customer licenses. How, exactly, depends on what you are doing for your customer, what your customer does, and your negotiating leverage. But it's certainly doable and happens everyday.

</comment><comment><USER5> You should speak with an attorney. They can teach you about all the various ways that your good intentions can go wrong.

</comment><comment><USER6> You'll need a lawyer to define what these 'techniques' are and how far they fall into intellectual property category.

If, in the middle of a project, you suddenly change brace style in your code? Nobody will care.

If you invent something like map-reduce? You can be sure the customer will own that invention.

There's a huge spectrum here. Lawyer up.

</comment><comment><USER7> I'd say it's worth defining a line between IP and copyright. If you can reapply a technique without giving away the companies methods then you should be okay. But get someone who understands legalise to advise.

</comment><comment><USER8> Those agreements don't make sense with open source if you ever want to upstream fixes (you do - the alternative is basically forking projects you use).</comment>


Happy Holidays from First Round Capital - <AUTHOR> http://holiday2009.firstround.com/

<comment><USER2> Brilliant. Along with being a classy holiday message, it's great social proof that startups are happy with them.

</comment><comment><USER3> If I'd known the video was going to get this kind of coverage I'd have rescheduled the meeting that confliected with this. Oh well...

</comment><comment><USER4> <http://www.youtube.com/watch?v=X0oyaA1iNFs>

</comment><comment><USER5> I just met with a partner from First Round today during their "Office Hours" in L.A. What a cool VC firm.

</comment><comment><USER6> What a great video.</comment>


Microsoft Edge: Microsoft's new browser - <AUTHOR> http://techcrunch.com/2015/04/29/microsofts-new-browser-will-be-called-microsoft-edge/#.up0lhs:b33i

<comment><USER2> The burning questions for me are;

\- Will Edge only be available to Windows 10 users or will there be an upgrade path and will it work on Windows 7 & Windows 8/8.1?

\- What are the developer tools like in Edge?

\- How fast is it? More specifically, Javascript performance.

\- Will releases come out more frequently keeping the browser up-to-date with the latest standards like Firefox, Chrome and Opera do?

\- Any plans to release Edge for other devices and operating systems, perhaps Mac?

I am pretty excited to see what comes of Edge, dropping the IE branding was smart, but as a front-end developer who has experienced years of pain thanks to versions of Internet Explorer less than version 10, it will take more than note taking, annotation, a new simplified design and Cortana assistant features to win me back to camp Microsoft from camp Mozilla as my day-to-day browser. I will be giving it a chance on launch and if Microsoft have finally solved the IE problem, I will use it as my default browser.</comment>


What is the best free svn GUI on the mac? - <AUTHOR>

Any suggestions?<p>I've got svn set up with xcode, but xcode support is lacking.  I can't find a way to tag commits. <comment><USER2> Honestly? VCS's and interfacing with them might end up being (if it hasn't already become) the next text editor-alike 'war'. Everyone has their own opinion for what to use and how to interface with it.

IMO, All the free Mac SVN apps suck (and some paid ones too). I've tried (Here's some suggestions to look into) svnX, Syncro SVN, ZigSource, that Finder plugin, using Xcode, command line, Versions.app and Cornerstone. Versions.app is the only one I didn't hate after 5 minutes of using. If I didn't get Versions.app, Cornerstone would probably get my vote.

My advice? Either get very comfortable with the command line or chalk up the $ and buy a copy of Versions.app or Cornerstone (Versions.app has a student discount, not sure about Cornerstone. Both have trials.) Neither is cheap for software (over $50) but in the long run, its not even a drop in a bucket compared to what you can make coding.

<comment><USER3> I must second the fact that there does not seem to be a decent free GUI subversion client for the mac. I tried a lot of them and they all came up lacking.

That said I liked versions the best of all the clients that I tried. To me it was worth every penny as I do not like fighting with the tools I use.

</comment></comment><comment><USER4> I've only tried one, but Tigris' own SCPlugin works well. It allows Subversion commands to be run from the Finder, and can badge Finder icons with current state, etc.

Though for things like tagging, I've grown accustomed to using "svn cp" on the command line, so I don't know if the GUI can do it.

</comment><comment><USER5> As a follow-on, do you have an SVN service (server provider) you recommend? Something like Google Code, but for non-open-source projects?

<comment><USER6> <http://svnrepository.com/> is pretty good.

<comment><USER5> Just what I was looking for, thank-you!

</comment></comment></comment><comment><USER7> Not sure about "best," but I use SCPlugin, which I find to be not as good as, but a reasonable approximation of, TortoiseSVN on Windows.

</comment><comment><USER8> beanstalkapp.com & svnX

</comment><comment><USER9> git-svn</comment>


Archery in the upcoming Robin Hood movie [video] - open-source-ux https://www.youtube.com/watch?v=DZsQmlZclTo <comment><AUTHOR> I've always found it really interesting how some people's jobs is to not only research historic artifacts, but research and verify what they had found out was accurate and repeatable. What kind of background do these people have that they can get into this line of work?</comment>


Fears of immigration in ancient Rome and today - <AUTHOR> https://eidolon.pub/barbarians-inside-the-gate-part-i-c175057b340f <comment><USER2> Of course, one should bear in mind what eventually happened to Rome…

<comment><USER3> Since the late 300s there was a repeating pattern where German tribes would want to become part of Rome (initially, fleeing the Huns), and the Romans would respond with acts of astonishing racism.

The first revolt of 376 began when the Romans reneged on land grants to the Goths (who were refugees from the Huns) and allowed them to starve. The proximal cause of its fall were anti-German riots in the Roman capital, where the wives and children of the German troops were massacred; leading the Gothic leader Alaric's troops to openly revolt where they were previously loyal to Rome.

So the fall of Rome has a lesson about the treatment and acceptance of foreigners, but maybe not the one you had in mind.

<comment><USER4> But didn't pluralistic and non pluralistic empires come and go back then? Did pluralism or non pluralism actually make a difference in the decline of empires?

If anything the Chinese who were ruthless in rule were able to keep things going the longest.

<comment><USER5> China was also very open to immigration and inclusive in what counted as "Chinese."

<comment><USER6> > China was also very open to immigration and inclusive in what counted as > "Chinese."

I'm pretty sure this claim is invalid. Say you took a measure of genetic diversity in various populations, I'm pretty sure you would find that Han Chinese are less heterozygotic than other neighbouring Asian populations. Take for example, their Southern neighbour, India, I predict you see far more genetic variation. I think this maps out to just looking at phenotype variation. I have travelled a bit through South East Asia and India, and just looking at visible attributes like skin color, eye color, hair color, and so on, one sees huge variation, also their languages are distinct (not even from a single linguistic family like Sino-Tibetian). In contrast, in China, where I have lived in, I found that the amount of variation was much smaller (just small differences between Northern Chinese and Southern Chinese) which I predict corresponds with much lower genetic diversity and thus the "openness to immigration" is quite suspect.

<comment><USER5> Here's an interesting pickle about linguistic diversity: Jane Austen is roughly temporally equidistant between modern day and Shakespeare, yet our level of mutual intelligibility is so much higher.

What changed? Standardization (such as printing a standard dictionary) drastically reduced the rate at which languages evolved. And one major historical difference between China and India is a history of unification, starting with the Qin Dynasty, which introduced dictionaries, standardized weights and measures, a single currency, and standard widths of roads. They were brutal in their implementation and it ultimately led to popular revolt, but the standards stuck. However, that would not be the last attempt at unification. In China's history, there have been repeated efforts at unifying an empire, splitting into multiple nations, re-unification, rinse, repeat. Have you noticed that all the terms that translate into "ethnic Chinese" in English are named after dynasties? At one point in time, identifying oneself as "Han" was like saying "I'm an American." Sure, my ancestors are a mix of Wu and Manchurian, but now we're part of the Han Nation. Or a different mix of other ethnicities for the Tang Dynasty.

To put it another way, let's say the EU became one nation that lasted at least a century. People who previously identified as "German" or "Italian" (or Anglos? Saxons? Celts?) all self-identify as European. Fast forward another century. The empire is expanding, and Central Asia is part of the equation now, so European is defined "as opposed to" another group, but another unification event happens, and now everyone on that continent refers to themselves as Eurasian. And sometimes, on the East Coast, there's an influx of Australian immigrants which adds up over the next century. How arbitrary is it to say that Eurasia is 95% Eurasian?

As for visual phenotype difference between Northern and Southern Chinese being "minor" \-- these differences look very pronounced to me. Yet I have trouble telling the difference between, say, British and German people, for instance.

Maybe we're just trained on different data sets?

<comment><USER7> One of the theory on face recognition is that we learn to recognized people by "storing" the difference between an average face and the people we are looking at. And we build that average face from the sum of all people we met.

[https://en.wikipedia.org/wiki/Cross- race_effect](https://en.wikipedia.org/wiki/Cross-race_effect)

So indeed the different training set has a big impact.</comment></comment></comment></comment></comment></comment></comment>


Refactoring – Not on the backlog - <AUTHOR> https://ronjeffries.com/xprog/articles/refactoring-not-on-the-backlog/ <comment><USER2> The idea behind the article is very good and the article itself offers some remarkable starting points.

However I think that it is not always easy to refactor only some parts of the code. As a matter of fact, when you have spaghetti code that needs to be refactored, every part of this code is strictly linked to other code and you end up to refactor everything, because there's not an easy way out :-)</comment>


How Tech Startup Founders Are Hacking Immigration - <AUTHOR> http://www.bloomberg.com/news/articles/2016-02-10/how-tech-startup-founders-are-hacking-immigration <comment><USER2> This article has an interesting point. I am from India. Built the biggest social network from India, sold a startup to Dropbox. Not sure if this is sufficient to get an EB-1 green card. With EB-2, I won't get Green card for another 5-8 years.

My next option is to invest a million to get EB-5, which is a waste of time. Or move outside US :(

<comment><USER3> You'd most definitely qualify for an O-1. You basically need 1 of 8 criteria, and the most common for software engineers coming in on O-1 are 1) High salary 2) press coverage of your transaction with Dropbox 3) being a judge at a hackathon.

<comment><USER4> Concur. Chris Wright down in LA is superb at O-1s, has worked with a lot of founders with positive conclusions. I recommend him highly.

<comment><USER2> Thanks. Got multiple recommendations for Chris Wright. Will reach out to him ASAP. Thanks once again :)

<comment><USER4> He's on Global EIR's legal advisory board, so I'm happy to connect you. I'm at Craig at globaleir org

<comment><USER2> Thanks Craig. Just dropped you an email.

</comment></comment></comment></comment></comment></comment><comment><USER5> The inertia of the US government on immigration in general and particular for startup founders is astonishing. Once a place like Vancouver or Berlin gets enough traction combined with money for investments, international founders will stop trying to get into SV

<comment><USER6> An optimistic comment about Vancouver on Hacker News that doesn't have anything to do with brain drain due to Chinese investors buying up real estate? Is it opposite day?

<comment><USER7> Come to Toronto. Much more funding, much less foreign ownership.

</comment></comment></comment><comment><USER8> The author could have do a bit better research, "research schools & universities" do not use H1B's they use J-1's for PhD's & Postdocs. Also a "rockstar visa" would be an O-1 visa.

<comment><USER3> As others have pointed out H-1B is very popular on college campuses as they are cap exempt and come in on the lower end of the "prevailing wage" scale (because they are typically young and inexperienced)

An interesting/alarming trend is that education institutions are "hosting" private companies as a sort of satellite office, where the developer is an employee of the university (to get around the H-1B cap) but all work is directed and owned by the company. So Acme Co. pays the PCU $20/hr and PCU pays the H-1B $15/hr and pockets the $5.

Ah the tangled webs we weave when at first we aim to deceive.</comment></comment>


Google's Prototype Self-Driving Cars Coming to Austin for Testing - <AUTHOR> http://www.siliconhillsnews.com/2015/08/30/googles-prototype-self-driving-cars-coming-to-austin-for-testing/

<comment><AUTHOR> Buried at the very end is an interesting bit on Google's timeline:

"Within four years, Google hopes to have the autonomous vehicles commercially available and citizens throughout the U.S. regularly riding in them"

</comment><comment><USER2> Many people here have taken selfies with the cars as they've spotted them around town.</comment>