[HN Gopher] The Rune Programming Language
       ___________________________________________________________________
        
       The Rune Programming Language
        
       Author : rurban
       Score  : 222 points
       Date   : 2022-11-27 07:36 UTC (15 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | ryukoposting wrote:
       | I don't really care about the security aspects of the language
       | (cool, but not earth-shattering), but I love seeing little
       | passion-project langs like this. I have been doodling a language
       | design for about a year now, and this one is eerily similar in
       | some ways, and totally different in others. I dig it.
        
       | [deleted]
        
       | vbezhenar wrote:
       | First example seems weak. Any language can use separate data type
       | for secrets and corresponding operator for constant-time
       | comparison.
       | 
       | Second example is very neat. Actually I thought about using
       | sqlite with tmpfs database for application state. That could be
       | useful for some kinds of applications. That said, using
       | functional API over traditional data structures seems like a
       | traditional and widely accepted approach. Interesting to see
       | where that experiment will go.
        
         | henrydark wrote:
         | But it's not just operator overloading, there seems to be a
         | monad-like "secret" that makes calls to func(a, ...) -> b with
         | secret(a) return secret(b).
         | 
         | The example doesn't spell this out explicitly, but I think
         | those are the semantics of secret.
        
           | aflag wrote:
           | What makes that different from creating a Secret class that's
           | just a container class and defines its own methods? I just
           | don't see what it is that requires a new language to
           | accomplish and couldn't just be implemented as a library in
           | many of the pre-existing languages (including popular ones
           | like C++).
        
             | mumblemumble wrote:
             | It seems like we're focusing way too much on just the very
             | first example, instead of the feature list as a whole?
             | 
             | There are plenty of other interesting features, such as
             | disallowing conditional branching on the contents of
             | secrets, all the way down to enforcing Spectre and Meltdown
             | mitigations around secrets _without_ necessarily globally
             | taking that performance hit on sensitive and non-sensitive
             | data alike.
        
               | aflag wrote:
               | I think I'm just not creative enough to think of features
               | that need to be implemented by the language and not
               | easily done at a library level. You could prevent the
               | access to secret's contents by creating the appropriate
               | class, but I suppose it would be harder or impossible to
               | allow the user to peak into the contents but disallowing
               | using them for branching specifically. Though, I'm not
               | sure where that can be useful in practice. Also, I'm not
               | sure how that language feature can mitigate meltdown and
               | spectre. How can it do that?
        
               | mumblemumble wrote:
               | I'm no expert here, but the arguments I can think of a
               | couple possible arguments. One is that it's not always
               | possible for libraries to ensure that programmers use
               | them correctly. This may be particularly true for systems
               | programming languages that often permit low-level
               | features such as pointers. The second is that the
               | compiler can do things that a library can't.
               | 
               | Spectre/Meltdown mitigation is a great example of the
               | latter. The compiler can be careful to emit instructions
               | that don't permit speculative branching, or disable other
               | optimizations that might expose a security risk.
               | Libraries don't typically get the kind of access that
               | would permit them to do that, and it's not clear to me
               | that a language that _does_ permit such access would be
               | appropriate for safety- or security-critical
               | applications.
               | 
               | As for why if statements are a security risk, they give a
               | tidy little example of that at the bottom of their
               | overview page, under the heading, "Can you see the
               | security flaw in this code?" I can't say I understand it
               | terribly well. I personally take that as a sign that,
               | while I can speculate about why they're doing things this
               | way, and even be arrogant enough to do so in public on
               | the Internet, I'm very, very, _very_ far from being
               | qualified to suggest that their basic approach is wrong.
               | Chesterton 's Fence sometimes strikes me as being
               | overblown, but Chesterton's Safety Belt is no joke.
        
       | the-smug-one wrote:
       | So there's also reveal() primitive for revealing secrets, as
       | shown by the code for msqrt(). OK, Rune gives you a library for
       | computing stuff in CT, but how do I implement something
       | independent of these things and show that they are CT? Do I still
       | need to rely on FM techniques such as relational symbolic
       | execution? Can I jump into a "constant" mode with a special
       | typing system or something that lets me do this without having to
       | run a more costly verification?
        
       | pphysch wrote:
       | This looks brilliant. I'm a sucker for languages that offer
       | strong support for relational modeling without slow
       | metaprogramming hacks.
        
       | Kukumber wrote:
       | Any language that's implemented in C++ already starts with a
       | handicap
       | 
       | That's nice to see they went with C
       | 
       | I like the syntax
        
         | sacnoradhq wrote:
         | What it's written in is meaningless except to religious folks.
         | Supposedly, they use lex and yacc, which means it's a toy.
         | Mainstream compilers use hand-written lexers and/or parsers
         | because they're faster and better.
        
       | andrepd wrote:
       | Quite underwhelming. The two main features seem to be constant
       | time operations on values wrapped with Secret, and easy SoA
       | layouts.
       | 
       | The former is trivial to implement in Rust and C++, the latter is
       | a bit more complicated, but also implementable in both via
       | macros, in a reasonably ergonomic way.
       | 
       | What is the advantage then?
        
       | ARandomerDude wrote:
       | > This is not an officially supported Google product.
       | 
       | Oh good, maybe it'll be here a while.
        
       | mhh__ wrote:
       | As per usual with benchmark results they are measuring how much
       | effort or knowledge the authors of the code had.
       | 
       | For example, in D you can write a container that automatically
       | switches from AoS to SoA but most benchmarks are just copy-pasted
       | C++
        
       | anhner wrote:
       | Is there any reason the `secret` type can't be implemented in,
       | say, Rust, or is it just Google getting really excited to
       | reinvent the wheel again?
        
         | kibwen wrote:
         | You can have a Secret type in Rust where the Eq, Add, etc.
         | traits are overloaded with constant-time versions. I'm unclear
         | if there are any semantics that operator overloading doesn't
         | address.
        
           | yccs27 wrote:
           | The secret (heh) is that any function defined on non-secret
           | arguments can automatically be applied to secret arguments as
           | well, and just returns a secret value now - without having to
           | think about mapping/monads/whatever.
        
             | mumblemumble wrote:
             | I think that it's actually something like the opposite of
             | that. Rune disallows conditional branching on secrets,
             | which would imply that passing secrets into the subset of
             | functions defined on non-secrets that branch control flow
             | based on an argument's value would be a compiler error.
        
       | simonebrunozzi wrote:
       | > This is not an officially supported Google product.
       | 
       | Then why is it under github.com/google ?
        
         | impulser_ wrote:
         | Because Google owns the code.
        
         | sideeffffect wrote:
         | Are there any officially supported Google products under
         | github.com/google ?
        
           | threatofrain wrote:
           | Even if there aren't, it makes sense to clarify to media that
           | this is an open source project made without any business
           | commitments. I've seen other businesses do something similar;
           | internally it reduces friction with the business admin when
           | devs want to open source something.
        
             | throwawaybutwhy wrote:
             | _without any business commitments_ - not to sound trite,
             | but when is the last time Google stood by its commitments?
        
               | ithkuil wrote:
               | Google still sells ads, doesn't it?
        
               | namkt wrote:
               | Didn't they originally claim to never show ads in search
               | given that it is in direct opposition to search results
               | quality? Back in the days when Pagerank was hot.
        
               | AlotOfReading wrote:
               | That was in the original pagerank publications. Google
               | had lots of other early attempts to make money that
               | avoided advertising (like the search appliance [0]), but
               | the firehose of money from ads dwarfed anything else they
               | could ever find and that early Google didn't last long.
               | 
               | [0] https://en.wikipedia.org/wiki/Google_Search_Appliance
        
               | ithkuil wrote:
               | Was that a "business commitment" or a "user commitment"?
        
           | xendo wrote:
           | Are there any officially supported Google products?
        
             | bheadmaster wrote:
        
               | pieshop wrote:
        
               | alex_smart wrote:
               | Are we Reddit yet?
        
               | memorable wrote:
        
               | rad_gruchalski wrote:
        
               | pieshop wrote:
        
               | 867-5309 wrote:
        
               | TylerE wrote:
        
               | halffullbrain wrote:
               | ?
        
               | [deleted]
        
               | aatd86 wrote:
        
           | ayewo wrote:
           | Would Google Guice count?
           | 
           | https://github.com/google/guice
        
         | IshKebab wrote:
         | The code is owned by Google because it was written by a Google
         | employee on the job.
        
           | csande17 wrote:
           | Or off the job -- Google claims ownership either way.
           | https://news.ycombinator.com/item?id=1969979
        
             | [deleted]
        
             | vitiral wrote:
             | IIUC you can request exception and have your own personal
             | projects, you're just supposed to be transparent about it.
             | Your request will be rejected if it completes with Google
             | business (like if you're making a new collaborative email
             | and docs solution), but otherwise I've not heard any sob
             | stories.
        
             | zelphirkalt wrote:
             | That would be one more huge reason not to work for them.
        
         | vore wrote:
         | I believe Google has a practice where all projects that are
         | copyright assigned to them are under github.com/google:
         | https://opensource.google/documentation/reference/releasing
        
           | xiaq wrote:
           | It's not a hard requirement, but they do make you jump
           | through extra hoops to put them elsewhere.
        
       | prirun wrote:
       | Instead of this:                 do {         c = getNextChar()
       | } while c != '\0' {         processChar(c)       }
       | 
       | I'd prefer:                 loop {         c = getNextChar()
       | break if c == '\0'         processChar(c)       }
       | 
       | The eyesight rationale for curly braces (screen readers) is
       | something I had never considered. But it would be nice if they
       | were optional. I've been writing Python for 14 years and have
       | never had a problem with mis-indenting.
       | 
       | Edit: I had to correct my post because Tabs were used in the
       | original, so alignment was all wrong.
        
         | mumblemumble wrote:
         | As someone who has some difficulty with reading sometimes, I
         | find Python's way of doing things to be a genuine readability
         | challenge. Python's the language I get paid to write, but, if I
         | thought I could get away with it at work, I might try
         | advocating we try out Hy simply so I could return to a world of
         | having visible, non-whitespace delimiters to aid me in reading
         | code.
         | 
         | I don't want to make too much hay about my challenges because
         | I'm not sure they realistically qualify as a disability. But my
         | own meager experience in this department does demonstrate to me
         | first-hand that "it would be nice if accessibility affordances
         | were optional" largely defeats the purpose of accessibility.
        
           | prirun wrote:
           | The braces could be automatically added or removed by any
           | editor, so I don't see the problem, unless someone wants to
           | write code like:                   if a == b {      do this
           | } else {       do that           }
        
             | mumblemumble wrote:
             | Arguments about what's easy to do in any editor lose a bit
             | of their shine in the post-GitHub era. Barring the
             | development of a really good language-aware semantic diff
             | algorithm that I'm guessing doesn't exist yet, you really
             | do need to have a consistent coding standard everywhere if
             | you want to avoid injecting unnecessary chaos (and, in this
             | case, accessibility challenges) into exactly the parts of
             | the modern software development lifecycle where code
             | readability is _most_ important.
        
       | noobhack wrote:
       | Haha
        
       | diarrhea wrote:
       | x^2 means x squared, orphaning the XOR operator. Rune is for
       | crypto, so math comes first.
       | 
       | Isn't XOR used very heavily in crypto? (As is exponentiation of
       | course)
        
         | namkt wrote:
         | I know, right? The strongest theoretical crypto is a one-time
         | pad, often presented in its XOR form in the first chapter of
         | every crypto book.
         | 
         | But hey, if Google says math comes first...
        
         | sacnoradhq wrote:
         | OTP is simply pt XOR giant-key.
         | 
         | It would've been wiser to duplicate C's bit operators ( ~ ^ & |
         | << >> ) than give the emperor some "new clothes."
         | 
         | Welcome to another "Not Invented Here" language dying to be
         | special and full of surprises. It's a fail.
        
         | troymc wrote:
         | It looks like Rune still has a bitwise XOR operator: @
         | 
         | https://github.com/google/rune/blob/main/bootstrap/database/...
         | 
         | That innovation does seem like a potential footgun.
        
           | sacnoradhq wrote:
           | Sheer insanity. Sensible languages use ** for exponentiation
           | and ^ for xor.
        
           | kibwen wrote:
           | Here's my hot take: if you're designing a new programming
           | language in the modern era, even a systems language, ignore
           | the precedent of C and don't use &|^~ as bitwise operators.
           | You can still have infix bitwise operators, but spell them
           | out as bitand/bitor/bitxor/bitnot. Then you can just use &|
           | for logical and/or, which are 1000x more common than bitwise
           | and/or, and you can reclaim ^ for exponentiation as well. And
           | don't forget to fix C's broken bitwise operator precedence
           | while you're at it.
        
             | mumblemumble wrote:
             | Interesting. I'd go the other way. Continue using single-
             | character bitwise operators, but spell out "and" and "or"
             | for the logical operators.
             | 
             | Rationale: in normal usage, short-circuiting logical
             | operators are, in effect, a special kind of control flow
             | statement, and control flow statements are typically
             | spelled out. Bitwise operators are more unequivocally meant
             | for calculation, and therefore perhaps more deserving of
             | similar syntax to the arithmetic operators, despite their
             | less frequent usage.
             | 
             | I think that this way of drawing the distinction might be
             | particularly relevant in a language that disallows
             | conditional branching - and, by extension, short-circuiting
             | logical operations - on certain kinds of data the way Rune
             | does.
        
               | nerdponx wrote:
               | This is exactly what Python did and it works out very
               | well for the most part.
        
             | lvass wrote:
             | Hard disagree on single characters for logic and
             | exponentiation. ASCII has too few special characters and
             | you'd want to use those elsewhere, without creating
             | ambiguity. Elixir got it right.
        
               | PointyFluff wrote:
               | ASCII has tones of unused chars we could grab for coding.
        
               | junon wrote:
               | Mm yes but BEL is not a character that can be typed on a
               | keyboard with any amount of ease.
        
               | [deleted]
        
               | dragonwriter wrote:
               | > ASCII has too few special characters
               | 
               | Unicode, OTOH, doesn't have this problem.
        
               | josephg wrote:
               | True, but we don't have Unicode keyboards.
        
       | halpmeh wrote:
       | Wouldn't it make way more sense to write this in C and expose a
       | typed API via language-specific packages. The functionality is
       | cool, but nothing stops you from forgetting to use secret(string)
       | instead of string.
        
         | TylerE wrote:
         | Seems kind of odd that you're arguing "just do it in C" and
         | "nothing stops you from forgetting" in the same post.
        
           | halpmeh wrote:
           | Why is that odd? You could provide a typed API in other
           | languages that leverages a suite of different side-channel
           | proof algorithms. In order to provide such an API, you need a
           | portable language compatible with the C calling convention
           | for FFI support in other languages. The only language that
           | meets such criteria is C.
        
             | joshuamorton wrote:
             | You can't provide an API that gives the security features
             | they want in c. The core feature here is a generic secret
             | type. In c that's a void*, defeating the purpose of the
             | typed, safe, API.
        
       | habibur wrote:
       | Written in C.
       | 
       | Uses LLVM for execution.
       | 
       | Parsers are Lex and Yacc.
        
         | sacnoradhq wrote:
         | So a weekend toy project.
         | 
         | Hand-coded parser-lexers are far more powerful because their
         | diagnostics are useful and are much easier to maintain.
         | 
         | Lex/yacc / flex/bison products by contrast have awful
         | diagnostics and become steaming piles of confusion that have to
         | be rewritten.
        
       | gus_massa wrote:
       | Why do they call it " _Python-inspired_ " if it looks like C++?
       | 
       | From
       | https://github.com/google/rune/blob/main/benchmarks/mandelbr...
       | for k = 0u32, k < 8u32, k += 1 {         cr0[k] = 2.0 * <f64>(8 *
       | x + k) / <f64>width - 1.5;       }
        
         | sacnoradhq wrote:
         | Minus static_cast or replacing C cast parens with angle
         | brackets.
        
         | nine_k wrote:
         | Not syntactically.
         | 
         | It's slot-based, vaguely like Python, and has reference-
         | counting GC, like Python. That's how I understand it.
        
           | boxed wrote:
           | So.. objective-c inspired? :P
        
       | pkolaczk wrote:
       | There already exists Rune programming language and that one was
       | earlier: https://rune-rs.github.io/
       | 
       | They should be more careful picking the name.
        
         | pipeline_peak wrote:
         | Whoever gets the stronger adopters gets the name.
         | 
         | A programming language is such a common personal project, it's
         | inevitable to not see this happen. It also doesn't help that
         | 95% of these languages aren't known.
        
         | rurban wrote:
         | The original title I submitted had the proper name for it. "yr
         | The Rune Programming Language"
        
         | FreeFull wrote:
         | There already was a GO programming language before Google
         | decided to use the name, too.
        
           | subtra3t wrote:
           | That doesn't justify them choosing an already chosen name
           | now, does it?
        
             | laumars wrote:
             | I didn't read the GPs comment as a justification.
        
             | Beltalowda wrote:
             | Rune (the existing language) is a fairly small hobby
             | project that only got started in 2020. The developer of
             | this new Rune probably just didn't know about it.
             | 
             | There is nothing nefarious here. There is no cabal. These
             | things happen _all the time_. I 've had it happen to two of
             | my own small/obscure projects. It happens.
        
             | sieabahlpark wrote:
             | Unless it's trademarked it doesn't matter in the slightest
        
           | tmtvl wrote:
           | Ah, so they're repeat offenders. How's it go again? Cache
           | invalidation, naming tconcurrencyhings, , and off-by-one
           | errors?
        
             | aredox wrote:
             | Google: - leader in AI and text generation - unable to find
             | or create original names for langs
        
               | Avicebron wrote:
               | Nah they're doing just fine. I was googling alien porn
               | and I landed here
        
               | shit_game wrote:
               | Given how poor their search engine performs as of late,
               | it's no surprise they can't seem to be original; they
               | obviously can't find anything that already exists.
        
               | gl-prod wrote:
               | Hey listen, namin things is really hard
        
           | kybernetyk wrote:
           | There also was a singer before Apple decided to name their
           | programming language ;)
        
           | xiaq wrote:
           | As some other comments have pointed out, this seems to be a
           | one-person project. FWIW, Go also started as a project by 3
           | people who happened to be working for Google (Robert
           | Griesemer, Rob Pike and Ken Thompson), so it wasn't Google
           | consciously choosing the name.
           | 
           | Perhaps Google as an employer shouldn't allow employees to
           | choose any name they like, and do some diligence to avoid
           | name clashes. This may sound quite reasonable for outsiders,
           | but internally this will be another step that requires manual
           | review in the process of publishing open source code, and
           | employees will see this as red tape and get discouraged from
           | open sourcing their code in the first place.
           | 
           | The benefit of requiring every project to go through a name
           | clash review is also questionable: there are 2.5k repos under
           | https://github.com/google, and most of the them will never
           | become popular enough for name clashes to be a problem
           | anyway. This repo only has 177 stars despite hitting HN
           | homepage.
           | 
           | IMO Google should instead make it easy for people to publish
           | their open source code wherever they like, but I suppose
           | there are some messy legal reasons why they prefer employees
           | to put their repos under https://github.com/google. (It's not
           | a hard requirement, but they do make you jump through extra
           | hoops to open source your code elsewhere.)
           | 
           | (I'm a Google employee, but I didn't know this project and
           | don't work for the department responsible for the process of
           | open sourcing code.)
        
             | wycy wrote:
             | It shouldn't need to be a company policy, you'd think a
             | competent engineer would simply do due diligence in naming
             | their project. I remember searching for name clashes for a
             | project I wrote solo when I was ~13 years old in the early
             | 2000s.
        
               | kweingar wrote:
               | Unfortunately Rob Pike, Ken Thompson, and Robert
               | Griesemer are not competent engineers by this standard.
               | I'm sure they'll be sad to hear it.
        
               | tom_ wrote:
               | The competence is assumed. The disappointment comes from
               | people who are competent not doing the due diligence that
               | some think should be par for the course when naming a
               | project.
        
           | throwaway50100 wrote:
           | Correction, there was a "Go!" programming language.
        
         | booleandilemma wrote:
         | One would think they would try googling it beforehand.
        
         | ohbtvz wrote:
         | Let's be real for a minute. A couple of hobbyists have named
         | their pet project "rune". Should the name be then forsaken for
         | all eternity?
        
           | ModernMech wrote:
           | Yes, actually, or at least until abandoned by the original
           | authors. That's pretty much the norm in the PL community.
           | There are enough names out there that no one needs to step on
           | any toes. Although I guess Google engineers don't care much
           | about community norms.
           | 
           | But in the spirit of being real: what are you trying to do by
           | calling the Rune devs "a couple of hobbyists"? Is that an
           | attempt to minimize them, as if they are not a corporation
           | therefore they don't have any naming rights to their
           | projects? "A couple hobbyists" are how many great language
           | you know and love started out. Their rights are important
           | too. We don't want the norm to be big corporations snuffing
           | out hobbyist projects by making them unsearchable, like
           | Google did to Go!. That's bad for everyone.
        
           | [deleted]
        
           | matheusmoreira wrote:
           | Let's be real for a minute. What you're actually saying is
           | these hobbyists don't really matter and they don't even
           | deserve to name their projects. Only Real Projects created by
           | Real Programmers at Real Big Tech corporations get the cool
           | names.
           | 
           | This is the kind of disrespect that pushed people to create
           | trademark laws.
        
             | alpaca128 wrote:
             | The actual issue here is you acting like a name collision
             | is a huge problem. It isn't, it's an everyday occurrence on
             | Github alone. We just add a bit more info, like the account
             | name in the case of Github or the year of release for
             | movies/series/games etc.
        
               | cmdrk wrote:
               | name collision becomes a problem when at least one of the
               | entities is willing to bring lawyers to bear. not saying
               | that's happening here, but certainly more of a concern in
               | a situation where you have a hobbyist going up against a
               | big company.
        
               | ModernMech wrote:
               | If a name really isn't such a big deal, then it shouldn't
               | be a big deal to change it to something else that wasn't
               | already taken. If there's resistance to that idea, then
               | maybe names are a big deal after all.
               | 
               | For a language dev, the name of the language is all you
               | really own about it. These days, developers expect their
               | languages and tools to be free, and of course open source
               | and permissively licensed. The name and logo of the
               | language is really the only IP most PL devs actually
               | fully control, and costs actual money and time to
               | maintain (registering and defending trademarks, domains,
               | etc.)
               | 
               | To just step on names like Google has repeatedly done
               | shows a crass disregard for what independent language
               | devs go through.
        
               | alpaca128 wrote:
               | We are talking about "rune", a common English noun. It's
               | not like Google called it Zig or Jai. And how many github
               | repos are just called "Lisp"?
               | 
               | Google isn't exactly innovative with their naming:
               | Fuchsia, Dart, Pixel, Go, Drive, Ara, ... Aside from rare
               | short-term experiments like Stadia everything outside a
               | basic dictionary should be safe.
               | 
               | I'm not going to defend Google, but this specific case
               | isn't one that I'd lose my mind over.
        
             | kweingar wrote:
             | Hobbyists do deserve to name their projects. And other
             | people can name their projects the same thing. Not a big
             | deal.
             | 
             | (By the way, the reverse scenario here should be okay, too.
             | If Google makes a project with with a common noun name,
             | then others should be able to use that noun to name their
             | projects.)
        
               | ModernMech wrote:
               | If Google can just stomp on anyone's name and that's fine
               | by you, then what does it mean to say that hobbyists
               | "deserve" to name their projects? What you're really
               | saying is that whoever has the loudest voice backed by
               | the most money gets claim over the name, regardless of
               | who had claim to it first. In that world, hobbyists get
               | whatever is leftover by by big corps, and don't really
               | "deserve" anything.
        
         | snidane wrote:
         | Who is the rightful owner of a name or similarly, a piece of
         | land, or an idea, patent?
         | 
         | The first settler? The first settler that held it for at least
         | a year, 10 or 100? The most powerful entity claiming it?
         | 
         | In the modern western mind there is the notion that whoever
         | grabs it first rightfully owns it. Which is a simple rule, but
         | encourages squatting and holding but not using. The squatter
         | can then hold ransom against somebody who would be the rightful
         | owner.
         | 
         | At least with patents or electromagnetic spectrum there is a
         | time of expiration. You come first and claim it for a few years
         | after which it becomes public domain. Or we hold an auction
         | each 5 years to maintain stable and efficient allocation of a
         | finite and scarce resource.
         | 
         | With concepts like programming languages, the case with
         | stronger base wins, like in the example of Go. People associate
         | the Go label with Pike's Golang, not with the previous Go!.
        
           | fla wrote:
           | When you say "Modern western mind", who exactly are you
           | referring to ?
        
       | nnoitra wrote:
       | Can someone explain the timing security vulnerability mentioned
       | in the article, I'm not sure I understand.
        
         | aflag wrote:
         | This is sort of classic problem. First, you need to assume the
         | attacker is capable of measuring checkMac's runtime reliably.
         | Second, you also need to assume the attacker is able to control
         | the message and the mac, but not the secret. How the attacker
         | got there is not really relevant, the point is figuring out
         | whether or not the system is possible to crack by having the
         | attacker full knowledge of everything, but the secret.
         | 
         | In most languages, a similar implementation of checkMac would
         | not pass the test, because they will usually implement some
         | sort of short-circuiting. Which essentially means that checkMac
         | will take longer to execute the closer you get to the true mac
         | of that message.
         | 
         | Let's say computeMac(secret, "a") == "a21a". The attacker could
         | pass in message="a" mac="0000" at first. Let's say that takes 1
         | unit of time, because "0000" == "a21a" only has to look at the
         | first character. So the attacker knows that 0 is wrong. They
         | then try "1000", then "2000", up until they get to "a000".
         | Then, the algorithm takes 2 units of time, the first one is
         | comparing '0' == 'a' and the second one is '0' == '2'. Now the
         | attacker knows the first character of the mac. They keep going
         | like this until they find out the entire mac of the message. In
         | a nutshell, the time the function takes to execute leaks
         | informartion that an attacker could use.
         | 
         | In this language, when you do use the secret(string) type, it
         | will always compare all the characters of the string, even
         | after it knows it will be false anwyay, just to make sure no
         | information is leaked.
        
       | chakkepolja wrote:
       | Interestingly the parser is generated using flex and bison, which
       | I thought was rare these days.
        
         | tgv wrote:
         | If you want accurate error messages, you might want to write
         | the parser by hand. If you want to make changing the grammar
         | easy, and have a reliable, correct parser, you use a parser
         | generator. Some have better error message than bison.
        
       | grantjpowell wrote:
       | ~I love when I see programming languages who's first advertised
       | features are implementable in 8 lines of rust~
       | 
       | Edit: ^ the above had the wrong tone. Thanks to dang for pointing
       | it out. What I meant to express was that it's possible to
       | accomplish a similar safety/ergonomics at the library level in
       | rust in not too many SLOC. My personal preference is towards
       | Rust's approach because the type system gives really powerful
       | composable primitives which makes it possible to have the
       | compiler check a wide range of invariants, instead of just the
       | ones that are common/special enough to go into the language
       | itself
       | 
       | (Example edited after comments from mumblemumble)
       | // The struct is public, but the contents are private, meaning
       | you can't directly access the secret once it's inside the struct
       | pub struct Secret<T>(T);              impl<T> Secret<T> {
       | // The only public way to access the secret, returns a new secret
       | pub fn map<U>(&self, func: impl FnOnce(&T) -> U) -> Secret<U> {
       | Secret(func(&self.0))             }         }
       | impl<T: AsRef<[u8]>> PartialEq<&[u8]> for Secret<T> {
       | // == does the correct thing (and only works for types that would
       | make sense (`AsRef<[u8]>`)             fn eq(&self, other:
       | &&[u8]) -> bool {
       | constant_time_eq(self.0.as_ref(), other)             }         }
       | /* Some other file */              use secret::Secret;
       | // Translated from the example         fn check_mac<T:
       | AsRef<[u8]>>(mac_secret: Secret<T>, message: &[u8], mac: &[u8])
       | -> bool {             // This returns a new Secret<[u8; 32]>
       | let computed_mac = mac_secret.map(|secret|
       | hmac_sha_256(secret.as_ref(), message));                  // This
       | uses the `constant_time_eq` impl from above
       | computed_mac == mac         }
       | 
       | Edit: It looks like you can implment SOA as a macro too
       | https://github.com/lumol-org/soa-derive
       | 
       | Edit: mumblemumble helpfully points out I demonstrated this
       | poorly, so I tried to better demostrate what I was going for in
       | this comment https://news.ycombinator.com/item?id=33764037
        
         | [deleted]
        
         | mumblemumble wrote:
         | This Rust example seems like it misses the point? Rune detects
         | that you're working with data that is marked as secret, and
         | gives you a _compiler guarantee_ that it 's defending against
         | some set of known attacks.
         | 
         | The Rust code above depends on the programmer to consistently
         | remember to enforce safety, and to do so correctly every time.
         | 
         | Sure, you could probably implement that as a library. But, "We
         | don't see much value in compiler help with this, a combination
         | of libraries and being careful gets the job done," would be a
         | peculiar position for a rustacean to defend.
        
           | grantjpowell wrote:
           | Great callout, I haven't had my coffee yet. Here is a version
           | that better shows what I intended                   pub
           | struct Secret<T>(T);              impl<T> Secret<T> {
           | pub fn map<U>(&self, func: impl FnOnce(&T) -> U) -> Secret<U>
           | {                 Secret(func(&self.0))             }
           | }                  impl<T: AsRef<[u8]>> PartialEq<&[u8]> for
           | Secret<T> {             fn eq(&self, other: &&[u8]) -> bool {
           | constant_time_eq(self.0.as_ref(), other)             }
           | }              /* Some other file */              use
           | secret::Secret;                  // Translated from the
           | example         fn check_mac<T: AsRef<[u8]>>(mac_secret:
           | Secret<T>, message: &[u8], mac: &[u8]) -> bool {
           | // This returns a new Secret<[u8; 32]>             let
           | computed_mac = mac_secret.map(|secret|
           | hmac_sha_256(secret.as_ref(), message));                  //
           | This uses the `constant_time_eq` impl from above
           | computed_mac == mac         }
           | 
           | I think the interesting part of the example is what you
           | _can't_ do in the other file. It's pretty hard to misuse
           | because the return type of `Secret::map` is a new `Secret`,
           | the only way to do `==` on a `Secret<T>` uses a constant time
           | compare.
           | 
           | I guess my main point is that when you have a instead of
           | having to add new things at the language _level_, if I have
           | something as powerful as the rust type system I can implement
           | the same functionality in not much of code.
        
             | yccs27 wrote:
             | It all gets more complicated when you want to pass more
             | than one secret parameter, or the function already returns
             | a Secret - now you need a monad. The key feature seems to
             | be that the code does not need 'map' or anything, the
             | secrecy flag is propagated regardless.
        
               | grantjpowell wrote:
               | > now you need a Monad
               | 
               | "need a Monad" sounds scary but in practice it looks like
               | this                   impl<T> Secret<T> {
               | pub fn map<U>(&self, func: impl FnOnce(&T) -> U) ->
               | Secret<U> {                 Secret(func(&self.0))
               | }                  pub fn flat_map<U>(&self, func: impl
               | FnOnce(&T) -> Secret<U>) -> Secret<U> {
               | func(&self.0)             }         }
               | 
               | If you need an escape hatch for something more
               | complicated, you could provide an api to that
               | impl<T> Secret<T> {             pub unsafe fn
               | reveal(&self) -> &T {                 &self.0
               | }         }
        
               | yccs27 wrote:
               | My point, which I didn't express well there, was about
               | the call side: How do you call
               | func(param1: A, param2: B) -> C
               | 
               | with both parameters being secrets (secret1: Secret<A>,
               | secret2: Secret<B>)? In Rust, it's
               | flat_map(secret1, |param1|           map(secret2,
               | |param2|             func(param1, param2)           )
               | )
               | 
               | or with do_notation at least a bit cleaner
               | do! {           param1 <- secret1;           param2 <-
               | secret2;           Secret(func(param1, param2));
               | }
               | 
               | whereas Rune manages it with
               | func(secret1, secret2)
        
             | mumblemumble wrote:
             | That covers the one case in the example, but the language
             | goes even further than that in ensuring constant-time
             | processing of secrets, including ensuring speculative
             | execution in the CPU won't expose the data to timing
             | attacks.
             | 
             | I don't know enough about the subject to really evaluate
             | this in detail, but I am more than willing to at least
             | entertain the notion that the problem space is thorny
             | enough that a language-level solution really can do some
             | things that can't be as effectively accomplished with a
             | library solution. Even in a language with a strong compiler
             | like Rust.
             | 
             | Rune also has an interesting approach to pointer safety
             | that's significantly different from Rust's: https://github.
             | com/google/rune/blob/main/doc/index.md#runes-...
        
         | dang wrote:
         | Please don't be snarky when evaluating someone else's work.
         | Your comment would be fine without the opening swipe.
         | 
         | https://news.ycombinator.com/newsguidelines.html
        
         | 3a2d29 wrote:
         | Compiler checking is always better than programmer checking.
         | 
         | As someone who uses rust, I assume you would prefer the former
         | absolutely.
        
       | WhiteBlueSkies wrote:
       | Can someone explain how this works:
       | 
       | "Assume the attacker can tell how long it takes for mac ==
       | computedMac to run. If the first byte of an attacker-chosen mac
       | is wrong for the attacker-chosen message, the loop terminates
       | after just one comparison. With 256 attempts, the attacker can
       | find the first byte of the expected MAC for the attacker-
       | controlled message. Repeating this process, the attacker can
       | forge an entire MAC."
       | 
       | How precisely should an attacker guess how long the comparison
       | runs?
        
         | wolf550e wrote:
         | You guess the MAC tag value of the message and measure how long
         | it takes the server to return "bad MAC" error or behave in a
         | way that means the MAC was bad. In 1/256 cases, it takes longer
         | because the first byte was correct. You may need to send many
         | queries to get the value because timing is noisy, but with
         | statistics you'll find that value. Now you try all 256 possible
         | values of the second byte and one of them will take longer
         | because both 2 first bytes are correct. Repeat.
         | 
         | For the normal way to safely compare MAC values, see for
         | example:
         | https://docs.python.org/3/library/hmac.html#hmac.compare_dig...
        
         | wolfwyrd wrote:
         | This is a timing attack or timing oracle. Lets assume a mac
         | represented in an array of 32 bytes. If we had a pseudocode
         | method like:                   byte [32] (actualMac,
         | expectedMac)         for int x = 0..31             if
         | (actualMac[x] != expectedMac[x])                 return false;
         | fi         end         return true;
         | 
         | We return false as soon as we hit an invalid byte in our
         | calculated mac. If the time taken to execute one iteration of
         | the loop is Y and the attacker is able to time this method
         | accurately they will be able to tell what the value of
         | actualMac is by feeding known inputs. They will know because
         | the return time will be 2Y when they have bailed after the
         | first byte. 3Y after the second, 4Y after the third etc.
         | 
         | This is why we should check the arrays in constant time -
         | compare every byte in both arrays before returning. We do not
         | return early so we can't leak information
        
           | TylerE wrote:
           | Don't really buy it. Seems to be both "spherical cow
           | optimistic assumptions" and "anyone who could seriously think
           | about pulling this off has nation-state level resources and
           | already 0wnz you and/or already has the rubber hose at hand"
        
             | kapp_in_life wrote:
             | Not really. It doesn't rely on that big of an assumption,
             | nor does it require nation state resources[0]. When you're
             | trying to find the secret you can make a bunch of requests
             | and measure for statistically significant change, which can
             | still be detectable beyond jitter & web server load.
             | 
             | Also ignoring the fact that calling
             | constant_strcompare(string, string) instead of
             | strcompare(string, string) when working with secrets isn't
             | that big of an ask.
             | 
             | [0] https://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf
        
           | hellfish wrote:
           | > in constant time
           | 
           | why is it called constant time if it isn't constant with
           | respect to array length? Just seems confusing because the
           | algorithm is linear without a short circuit
        
             | namkt wrote:
             | It's constant time in that it always takes the same amount
             | of time regardless of the extent to which the two strings
             | are equal. It is a different concept than constant time in
             | complexity analysis.
             | 
             | What's even more confusing is that it is also constant time
             | in the complexity analysis sense given that the mac is
             | usually a fixed-size string after choosing a hashing
             | algorithm.
        
           | fweimer wrote:
           | Isn't it sufficient to compare 64 bits at a time? Then the
           | oracle becomes rather useless.
           | 
           | Many current memcmp implementations use such large
           | comparisons because they avoid hard-to-predict data-dependent
           | branches for extracting the specific point of mismatch.
        
         | nmadden wrote:
         | Coda Hale's old article on the topic is still good:
         | https://codahale.com/a-lesson-in-timing-attacks/
         | 
         | (Note that Java's MessageDigest.isEqual has been constant time
         | since shortly after that article and you should use it rather
         | than writing your own in Java).
        
           | pharmakom wrote:
           | Freddy the Pig?
        
             | nmadden wrote:
             | Ha! Wow, looks like there is a redirect when the referrer
             | is HN...
        
         | rurban wrote:
         | with secrets the timing safe stdlib variants are used, without,
         | the fast ones.
         | 
         | timing safe means always using the full loop and not branching
         | away on certain values. every value needs the same time.
        
         | JohnBooty wrote:
         | They wouldn't be guessing, they'd be measuring. I'm not
         | qualified to really explain more but if you want to learn more,
         | "timing attack" is what you're looking for
         | 
         | https://en.wikipedia.org/wiki/Timing_attack
        
         | lgeorget wrote:
         | By how fast the function returns.
         | 
         | This is white-box security, a hypothetical setting where we
         | assume the attacker has access to the entire knowledge of the
         | system and to every oracle they want (like an oracle telling
         | them how much time each function takes), but don't know any
         | secret, like private or symmetrical keys. If you can prove that
         | your function is secure in that setting, then it's secure in
         | real-case situations where the attacker knows even less.
        
         | [deleted]
        
         | csmpltn wrote:
         | So-far, all comments on this thread are about the general
         | concept of timing attacks...
         | 
         | You're asking a different question, though. You're asking about
         | precision.
         | 
         | The answer here is that in many cases timing attacks pose a
         | _theoretical risk_ , but they can't be exploited _in practice_
         | due to a low signal-to-noise ratio.
         | 
         | It really depends on the attack vector.
         | 
         | Measuring the latency of a network call (TCP) from across the
         | other side of the world, as an example, is going to be too
         | noisy (in many cases). Especially if the attacker wants to
         | remain covert.
        
       | greybox wrote:
       | I'll be interested to see how this compares to Nim (the other
       | python-similar systems programming language).
       | 
       | Very interested in trying seeing how it's 'SOA memory management'
       | turns out in practice.
        
       | kevingadd wrote:
       | I'm perfectly fine seeing nullable references in a new systems
       | programming language, but it's disappointing that nullable is the
       | default. If you care about both performance and memory safety,
       | being able to compile-time guarantee that you don't need a null
       | check in a specific location can be big!
        
       | DefNotMe wrote:
       | _This is because we didn 't just kill Abel, we destroyed Abel,
       | and this caused all of Abel's children to be recursively
       | destroyed._
       | 
       | TT
        
         | namkt wrote:
         | The Destruction of Abel, Jeremiah 27:14.
        
           | sacnoradhq wrote:
           | Sigh. There's enough religion in programming languages
           | already. Can we not add or xor actual religion?
        
       | natas wrote:
       | I like the syntax a lot
        
       | colonwqbang wrote:
       | Implicit nullability of all values, a very dubious design
       | decision in a new language.
        
         | henrydark wrote:
         | Given that they mention SQL more than other things, and stress
         | SoA and memory intensive applications, I think this makes more
         | sense than it would otherwise
        
           | colonwqbang wrote:
           | SQL null is not like the null of programming languages, it
           | behaves more like "unknown" than "blank". For instance, null
           | != null. Arithmetic on null values is also well-defined so
           | that 1 + null = null.
           | 
           | I'm not convinced that implicit nullability is a good idea,
           | either in SQL or in newly designed languages.
           | 
           | I don't see the connection between implicit nullability and
           | SoA. If you have a link to some example, that would be
           | interesting to read.
        
             | henrydark wrote:
             | I'm not convinced so either, just that it doesn't not make
             | sense.
             | 
             | As for SoA, I'm thinking of two relatively new formats and
             | applications that have default nullable types, are SoA, and
             | are specifically targeting memory intensive applications:
             | apache arrow and duckdb, both seeing some success and well
             | deserved hype
        
           | runeks wrote:
           | Go on...
        
           | kibwen wrote:
           | Even if you want to allow nullability, you can make it both
           | explicit and opt-in rather than implicit and opt-out.
        
       | C2H4O2 wrote:
       | Now, it is all just a race to replace C++ as quickly as possible.
        
       | aliqot wrote:
       | Syntax reminds me of Go. I'm looking forward to trying this out.
        
       | fidgewidge wrote:
       | It's got some novel ideas: better than many new languages!
       | 
       | Don't quite grok why it eliminates the need for ref counting
       | though. Tree structures are fine when you have them, but
       | frequently you don't. The docs claim Rune programmers _never_
       | write destructors even though there 's no GC, so is there no
       | equivalent of RAII? How do you model graphs?
       | 
       | The constant time stuff doesn't matter. Virtually nothing needs
       | to be constant time like that and when it does you're probably
       | writing in assembly anyway.
        
         | namkt wrote:
         | I think the point behind "constant time" here is that the
         | comparison always takes the same amount of time, and not based
         | on how many characters in the two strings are equal, to prevent
         | a timing attack. "Constant time" isn't very accurate here
         | because given a choice of hashing algorithm, the hash is a
         | fixed-length string and therefore even a trivial string
         | comparison technically "runs in constant time", at least if we
         | allow the typical abuses of language in CS.
        
           | fidgewidge wrote:
           | Yes, but my point is that there are only a few use cases for
           | this, mostly in cryptography, and to ensure something is
           | genuinely constant time you have to write in assembly. The
           | routines needed are small enough and compilers hard enough to
           | trust that you just bypass them in practice, so it's an odd
           | choice for something to build into a language syntax.
        
         | TylerE wrote:
         | I suspect for the kinds of projects this might in theory be
         | targeting, they aren't doing any dynamic allocation at all.
        
       | nine_k wrote:
       | Pretty interesting: imperative programming meets relational DB
       | models meets column store, with a serving of constant-time
       | operations on top for data marked as secret.
       | 
       | Also, memory-safe _and_ blazingly fast in certain circumstances.
       | Not complete though, some tests currently fail.
        
       | auggierose wrote:
       | Looks like Swift.
        
       | taspeotis wrote:
       | > The only close competitor is C++, where the author uses the
       | little-known MemoryPool class from the <memory> library.
       | 
       | I was like I know C++ and I've never heard of MemoryPool.
       | 
       | Turns out that MemoryPool doesn't exist in <memory>. In the
       | source code they're talking about it's an alias to
       | std::pmr::monotonic_buffer_resource.
       | 
       | https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
        
         | cormacrelf wrote:
         | Why would the struct-of-arrays layout be beneficial in a binary
         | tree where every single node is visited, and the left + right
         | arrays constitute all of the data in the tree? The previous
         | example they gave was touching 75% less memory. In the binary
         | tree it's the same amount of memory. Is the order it's touched
         | better somehow?
        
           | blep_ wrote:
           | Some memory-touching orders are better than others, because
           | CPUs will prefetch nearby memory into CPU cache during memory
           | accesses.
        
       | nsajko wrote:
       | This is an interesting idea for language design:
       | 
       | > Users of Rune are protected, because the compiler sees that
       | macSecret is secret, and thus the result of hmacSha256 is secret.
       | The string comparison operator, when either operand is secret,
       | will run in constant time, revealing no timing information to the
       | attacker. Care must still be taken in Rune, but many common
       | mistakes like this are detected by the compiler, and either fixed
       | or flagged as an error.
        
         | colonwqbang wrote:
         | I mean, this would be relatively easy to implement in any
         | language that have operator overloading.
        
           | henrydark wrote:
           | How do you operator overload in C++ so that calling
           | computeHmac(secret(string)) returns secret(string)?
        
             | vitiral wrote:
             | Define the computeHmac method to return a secret(string)
             | type?
             | 
             | Then define the equals operator for "secret" to behave in
             | the needed way.
        
               | henrydark wrote:
               | But now you've forced computeHmac to only work only
               | secrets, when there is no such need. You've coupled an
               | implementation of an abstract algorithm with the
               | particular case that _you_ want to use it this one time
               | with sensitive secrets.
               | 
               | The advantages of monads include exactly the opposite
               | decoupling: the hmac algorithm implementation is true to
               | its bare specification, and it is the context that
               | changes some of its behavior.
        
               | aflag wrote:
               | You could overload computeHmac's return value so that it
               | would return either a string or a secret, then you could
               | use it directly with checkHmac, if you wanted, or as a
               | string in other applications.
        
               | henrydark wrote:
               | Consider this: I don't even know what hmac is, and it's
               | implemented in a library.
               | 
               | Also, I can't overload return values on their own in C++,
               | I would have to overload the whole signature. In fact, to
               | get the same monadic result, I need 2^n-1 overloads for a
               | function with n arguments (one for each subset of the
               | arguments except the empty one).
               | 
               | Of course monads' advantages can be coded directly, just
               | as functions can be coded directly in assembly.
               | Personally I code in C++, so I've never used proper
               | monads, but I see where they save work.
        
               | aflag wrote:
               | I was just considering a nicer interface for computeHmac
               | at a library level, but if you don't have that, you could
               | still just implement checkHmac using your Secret class
               | and call it with checkHmac(Secret(str), message, mac).
        
               | henrydark wrote:
               | It's turtles all the way down. Without the secrets monad
               | support in the language, at some point I have to be the
               | one enforcing secrets in multiple places: if I implement
               | checkHmac(secret(str),...) that calls
               | computeHmac(str)->str then I must both "unbox" the
               | secret(str) _and_ "box" the return value of computeHmac.
               | 
               | I can do this, sure, and if I forget then I'll have a
               | security bug. This is similar to the situation with c++
               | destructors over c's manual malloc+free. If you're happy
               | freeing at every function's end, then this secrets thing
               | adds nothing for you, and that's cool. It's your own
               | choice what language to use.
        
               | aflag wrote:
               | If you try to call computeHmac from checkHmac surely
               | you'll get some sort of error or warning, wouldn't you?
               | You have no guarantee computeHmac will your secret will
               | be treated as a secret by computeHmac, if its signature
               | is simply "str". Unboxing it is never safe.
        
       | jstx1 wrote:
       | What's up with having two different new experimental languages
       | from Google on the front page
       | https://news.ycombinator.com/item?id=33756800 - did Google just
       | happen to release them at the same time?
       | 
       | I think when Carbon came out people's reaction was stronger than
       | deserved (like saying that Google don't believe in Rust, or that
       | Go has been a failure because it hasn't replaced C++ etc.) while
       | in reality all of this is very experimental and very early in its
       | development. I kind of expect similar reactions to Rune and
       | Mangle with some people trying to make a big deal out of nothing.
        
         | rvba wrote:
         | Promotion cycle, new _unfinished_ languages.
        
         | dvirsky wrote:
         | This isn't an official Google project, the contributions seem
         | mostly from one person, so probably someone doing this as a 20%
         | project. Carbon OTOH has a team working on it AFAIK.
        
           | TylerE wrote:
           | And it's not new, either. First commits to the repo are well
           | over a year old.
        
             | telmo wrote:
             | That's pretty new for a programming language.
        
         | xiphias2 wrote:
         | It seems like somebody got too easy access to the Google Github
         | repo. Usually only higher quality projects get approved to the
         | central repo.
        
           | rurban wrote:
           | Wrong. This is in a late state, and very high quality.
           | 
           | And Google is not really known to release high quality
           | projects overall. Only some of them are.
        
           | floitsch wrote:
           | If I remember correctly we were supposed to have our personal
           | projects there.
           | 
           | Since Google owns the copyright it almost makes sense.
           | 
           | Also, being in the Google organization doesn't mean that
           | Google is involved in it. I'm maintaining a project there
           | (`google/double-conversion`), despite not having worked for
           | Google for years. Nobody at Google has any influence or
           | reviews on that project.
        
             | jpace121 wrote:
             | This. Google's policy is kind of dumb (I write a lot of
             | stuff for fun that no one wants the ownership of... The
             | primary value is I learned something that I can use later
             | on something important),but pretty much any experimental
             | thing some one at Google works on will wind up there even
             | on their free time.
        
       ___________________________________________________________________
       (page generated 2022-11-27 23:01 UTC)