The Majority Illusion in Social Networks - <AUTHOR> http://arxiv.org/abs/1506.03022 <comment><USER2> High-engagement obsessives are another key to this. In a community where it's nobody's actual job to spread knowledge and values of the community, the highest-volume interactors – the most engaged – become standard-bearers of the community. Since they are often more obsessive and dedicated yet visible, this raises the stakes of the community to greater obsessiveness and dedication.

In online scenarios, the result is that many can say, well, I am dedicated to X, but I'm not as extremely dedicated as Y... where Y may be literally one of the most X-dedicated people in the entire world.

When you have this majority illusion, some high-engagement obsessives, and throw in some producers of writings (news, documents, popular literature and orientation literature such as FAQs), you have an engine for converting dedication into social goods such as a sense of belonging, friendship, and most of all, self-identification.

The ability to create and sustain these communities in many forms, for any topic, worldwide, is the miracle of the internet.

<comment><USER3> I've always wondered why social networks like Reddit make no attempt to throttle their loudest members. If you have a small minority who upvote/downvote an extremely high number of posts, they will easily drown out any votes cast by people who are more measured in their voting behavior.

It seems like there are so many fundamental ways in which the most popular social networks and discussion forums are flawed.

[http://www.thecaucus.net/#/content/caucus/community_blog/103](http://www.thecaucus.net/#/content/caucus/community_blog/103)

<comment><USER4> Because Reddit was written by young undergrads in their college dorm who haven't had the decade of experience with vote manipulation that Slashdot had by that time, let alone experienced the rise and decline of Usenet.

Indeed by 2006 the mature Slashdot moderation system - after a deluge of invasions by trolls and agenda-pushers - already had a lot of the tools that Reddit is still missing or eventually reinvented badly - limited number of upvote points, meta-moderation etc.

</comment></comment></comment><comment><USER5> We need a social network designed from the ground up to be a public square for civic discussion between people who disagree. We need mechanisms to agree on facts, and tools to create arguments supported by those facts.

<comment><USER6> A nice ideal, but likely to be very difficult in practice, because in reality almost nobody disagrees on actual provable, scientific facts. The toughest disagreements usually arise around things which are _not_ facts, but are presented as if they were.

All human subcultures carry with them a large baggage of "facts" which the group accepts in order to promote social cohesion, avoid conflict or sometimes simply to advertise membership of the group. Try convincing a highly religious person that their religion is entirely fact-free, or that God doesn't exist using logic, and you will get nowhere: they prefer to believe things that other people don't because believing these things grants membership to a group and the benefits of that membership are perceived to outweigh the benefits of being a person of pure rationality.

Indeed, a genuine belief that you are entirely rational is simply another form of group membership signalling: probably that you want to be seen as a member of the group "intellectuals" or "scientists" or possibly "educated people". Being unable to recognise the difficulty people have in being entirely rational is itself a form of irrationality.

So to get back to your proposed social network, here's what would happen: it would very quickly become dominated by a particular _pre-existing_ social subculture, probably "male internet geeks who believe themselves to be supremely rational" and their baggage of pseudo-facts would come along for the ride.

This is NOT an argument against doing what you want to do. Even if the goal is unattainable, creating better discussion forums with better tools for raising the level of discussion is never a bad thing. Just don't think it'd solve the 'friendship paradox' discussed in the paper.

<comment><USER7> > Try convincing a highly religious person that their religion is entirely > fact-free, or that God doesn't exist using logic, and you will get nowhere

Lets keep religion out of HN, shall we?

A lot of us actually seems to believe in some kind of deity/ies, we just dont mention it because we value HN as a common ground for technical and business discussions.

If not I could tell you some stories about stupid, stubborn evil ateists as well :-P

<comment><USER8> > Lets keep religion out of HN, shall we?

As a religious person, I find keeping religion out of normal discourse has been very counterproductive for both religious and non-religious people. I understand that the discussions are more prone to conflict and uncomfortable feelings, but they're nonetheless key to understanding other people and diversity of thought.

Keeping religion (and agnosticism and atheism) out of things produces the same problems we see with the 'Majority Illusion'.

<comment><USER9> The arguments get very tiresome quickly. There are a million other places online to beat the same dead horse of 'what is evidence, etc'. Keep it out of HN.

<comment><USER8> Equally tiresome political issues are on here all the time. There are also fairly regular (and equally redundant) back-and-forths about programming languages.

<comment> steve-howard At the very least, the political issues and programming language fads have changed in the last few centuries.

<comment><USER8> As have particular religious movements, but most people don't know about that because they are considered off topic in the news, at work, and in polite company.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER10> My biggest fear about FB isn't regarding privacy, but its enormous ability to spread misinformation.

<comment><USER11> Pamphlet, newspaper, telegram, radio, telephone, television..

<comment><USER12> Indeed, I think the problem with Facebook, is that like Television it is _not anarchic enough_.

A society with free speech is supposed to tolerate the expression of really bad ideas partly because nothing other than the consent of human minds lets society distnguish good ideas from bad.

But no particular organisation has a duty to be a forum for all ideas. And that's why it's OK to kick a racist out of your dinner party, and OK for reddit to try and censor its worst users. But when such organisations are main forum for conversion, then the censorship starts to look total.

</comment></comment></comment><comment><USER13> TL;DR: if highly connected nodes tend to have a given attribute, most nodes have the illusion that the majority has that attribute.

It's an interesting statement, but not terribly insightful. I hope more research follows.

</comment><comment><USER14> arxiv postings should feature warning sign iconography. On one hand, it offers open access to research -- awesome. On the other hand, it offers us a chance to waste our time and energy studying material that may never survive peer review.

I get excited whenever I see what appears to be a really interesting, valuable piece of information gleamed through rigorous research. My immediate first emotion is excitement. However, that excitement casts a long shadow of doubt as my system 2 mode of reason kicks in and alerts me that the content of interest is the result of an arxiv posting that may fail to survive peer review. Of course, death-through-peer-review may not imply bunk science but I assume that it more often is the case (experts, please chime in).

This leads me to ask whether the HN community would be better without knowing of bleeding edge research on arxiv until it's graduated peer review --What do you think: Is it better to front page bleeding edge, unverified research?

I think the world would benefit by a service that indexes arxiv postings that have survived peer review. Is this feasible?

<comment><USER6> Surely the act of people reading it _is_ peer review? Unless you assume that nobody on Hacker News is qualified to read scientific papers, which seems like a stretch.

<comment><USER15> For any given arxiv article, I'd wager 98% of people on HN are unqualified to critically review the article. They're not aware of prior work that might contradict the article. They're not aware of the limitations of prior work that the article cites. They've never tried the experimental or theoretical methods the article uses, and so on. Yet these are the people upvoting and commenting on implications.

<comment><USER6> 98% sounds like a made up stat, so if you grant me the same privilege then let's say HN has 1 million readers. So 2% of that would be 20,000 people qualified to judge the article, which is plenty of people.

<comment><USER15> 1) HN has 300k daily uniques ([https://news.ycombinator.com/item?id=9219581](https://news.ycombinator.com/item?id=9219581)). Of those readers, _nearly all_ do not comment (we don't have 300k comments, do we?). Of those commentors, only a fraction comment on a given article.

2) Of those commenters, most are not actual researchers, who are, IMO, much, much busier with real work (you know... _research_ ) than your average HN commenter.

<comment><USER6> Of course most don't comment, but commenting is not required for a paper to be peer reviewed, only reviewing it is. If someone were to see the paper here, and review it, and find an error, presumably they would contact the author.

300k * 0.02 = 6000 people who may be qualified. How many people are typically asked to peer review a paper? A handful? The odds are still good.

<comment><USER15> The original poster was talking about what would be better for the HN community. The HN community is a discussion forum, not a system of people privately emailing.</comment></comment></comment></comment></comment></comment></comment>


Ask HN: Did pay-to-play games really ruin the gaming industry? - <AUTHOR>

My question is why are the "exploitation" techniques employed by TCG of the past widely accepted while mobile games, such as clash of clans, cause an uproar in the community and have a bad rap? The general idea I get from reading articles about pay-to-play games is that they are the first to use this evil business model, but this is simply not true. Why has clash of clans angered the community to a near boycott while TCG remain as a nostalgic reminder of our younger years? <comment><USER2> Because the most common format isn't really pay to win, it's pay to avoid grinding.

Gamers have weird psychological issues with grinding in games.

Some of them like the delayed rewards from grinding and feel that people who don't are lazy and lack a work ethic. This group finds paying to avoid grinding immoral.

The other major group hates grinding in games. These people see the pay to avoid grinding option as the developer asking for money to not be an asshole. Mid game. So they aren't thrilled about it either.

The other issue is that grinding isn't supposed to be a big deal in games because the grinding activity is supposed to be enjoyable. The F2P market is designed around it not being enjoyable.

<comment><USER3> To add on your point - the "grinding" is designed to be very different.

If for whatever reason your game concept involves parts of grinding (say, extending game length; allowing less-skilled players to gain extra power by extra grinding to complete challenges they otherwise couldn't; providing less intensive background time to facilitate communication/chat in a MMO; etc), then in a 'pay' game you still try to optimize the grinding actions to be as fun as you can make the grind to be; but in a F2P game you would optimize the grinding to be _intentionally frustrating_ in order to push players over the edge of paying.

And that whole concept of mutilating a fun activity to be frustrating is a bit evil.

</comment></comment><comment><USER4> Some of the differences between trading card games, shareware etc and pay-to- play:

1) The older models have transparent pricing, whereas pay-to-play have opaque pricing. You can tell the price of a deck or full version of a shareware game, but you can't tell how many IAP's you'll need over the lifetime of a pay-to- play game.

2) When something is "free!" but actually not, it is a bait and switch technique ([http://en.wikipedia.org/wiki/Bait-and- switch](http://en.wikipedia.org/wiki/Bait-and-switch)). This leaves many consumers with a feeling of being tricked.

3) IAP's are often transient replenishables such as gems or gold. A trading card or full version of a game, you own permanently.

4) It's hard to trust that pay-to-play games isn't specifically designed to make you part with dollars. Players come to doubt the fairness of the game rules. Even for "honest" game makers, there will be suspicion of foul play in the game mechanics.

5) Pay-to-play games, like slot machines, make their money from 10-20% of users called "whales", who are susceptible to gambling addiction. Using psychological tricks to extract money from such people is very shaky, ethically.

When games promote feelings of suspicion, exploitation and even psychological manipulation in the majority of players (i.e. non-whales), you get this kind of backlash, as in the case of clash of clans and other pay-to-plays.

Has it ruined the gaming industry? Not in my opinion - I think (or hope) pay- to-play is a fad which will devolve into a niche. As people become aware of the shady tactics being used, they'll tend to avoid them. Or at least gravitate towards those pay-to-plays, where it really is possible to have a decent game play experience without paying.

</comment><comment><USER5> The pay to play games like the old Arcades that took quarters and tokens didn't, mobile free to play won't either.

Free to play is a market reaction and people do play them and it is becoming the only way to get revenues as a game developer. But there are plenty of other games out there and games for every consumer, free to play, premium, etc. In most free to play games most people pay less than premium games, it allows games to reach the people.

The thing about the current free to play market is some do it well like Valve, Halfbrick etc that add to the fun of the game usually through customization and vanity additions, but others it is part of the game design and much like social games where it is metrics over gameplay. It just serves another consumer, even if that doesn't interest old school lots of content and pay up front gamers.

Done well, in a way it is a return to the Arcade but much more cool in that you can customize the game and get more from it with additions, which do cost time/money to produce. Games also want you to play for a long time now, or many times in small increments, where before arcade games were made harder to skimp on content and get more quarters.

[http://www.polygon.com/2014/2/6/5386788/when-was-the-most- ex...](http://www.polygon.com/2014/2/6/5386788/when-was-the-most-expensive- time-to-be-a-gamer)

</comment><comment><USER6> Actually, I quit Magic: the Gathering exactly because of its pay-to-play and pay-to-win aspects. The deck-building is absolutely fun, but I didn't want to keep sinking money into it. But I still love a friendly game with others.

I don't think Clash of Clans is pay-to-play or pay-to-win. I don't pay a dime and am perfectly able to play it quite effectively.

The real problem with many of these free "social" games, however, is that they've turned micromanagement into the actual game. Quite often, there's very little strategic choice to be made, you just need to check in regularly to give new orders because you can't queue your orders.

Back in the '90s, people used to complain about the micromanagement involved in many big games. Designing your empire in Civilization is fun, choosing spots for new cities it, selecting new research is, but managing every individual city and unit gets really tedious after a while. And for some reason, this modern genre of games has removed all interesting decisions from their games and turned the tedium itself into what the game is about. You can't queue stuff, or at least not a lot, and you have to earn the privilege to avoid a small part of the tedium of micromanagement. Less micromanagement has become the reward for playing. And yet without it, there's practically no game.

Clash of Clans is not remotely the worst in this; designing your defense and organizing your attacks are still interesting parts of the game. But without those, you'd get a game like Hay Day which has practically no recognizable game underneath all the tedium.

But all of these games, including Clash of Clans, eventually have to make money for their developers, and they do so by making the game less fun than it needs to be, and you can pay to skip the unfun parts. And some people are suspectible to that, and end up paying. And the real evil of it is that they prey on addictive tendencies to get a few people to pay a lot.

But in the end, the games are intentionally designed to be less fun than they could have been.

</comment><comment><USER7> There is something to be said about the problems that have resulted from the very issue of pay-to-play. The problem is that its not just simply possible to classify it as a "pay to play" game, there are differences in quantification of their value add and their platform of playing - and its basis of its commercialization.

With MMOs, you have a very clear 1:1 value of purchase. The yielded "product" is the sustaining of the very service itself. No different than your internet service, cable TV, etc. These games have found that this isn't necessarily a sustainable model, as there is (as we all know) a clear disparity between those that can afford the monthly fee and those that cannot. Eventually if the game loses its overall worth, either by content, quality or service, then those that are minding the budget will leave with little convincing. That's the reason they went to the new micro-transaction model. By offering varied levels of shiny, the tab so to speak is picked up by those who can afford an excess... in effect carrying those who cannot, and allowing for all to play. In turn, the popularity of such an environment establishes word of mouth... as everyone wants to play with their friends. The ecosystem develops, and thus you have a reasonable model. This has worked for LOTR:O, STO and SWTOR. Even EVE online has adopted a model that is in the middle, whereby a user who is sufficiently established in the real world can purchase time for others, and establish their own fortunes in game thanks to the work of those who can't afford it in the medium but can afford it in the virtual.

In these cases the difference in overall representation is simple: You do not gain anything by the value adds except novelty. On the rare occasion you will get something of strength/power, but its not a permanent superiority: its merely early access. The entire reason it has become the model of success it is, is due to its availability to the masses in a harmless form: you get to pay for cosmetic differences only. This was actually the source of quite a bit of humor in season 1 of PA/PVP's The Trenches comic. There is nothing technically or physically better about the item, it only looks different or sounds different. But, it costs money... and it is unique. By being unique, one feels special - and by that it becomes valuable. That 14.99 item now becomes the monthly fee for someone else.

The other model, however, employs the opposite effect. This is the most visible one in the mobile world. Money buys you superiority. It may be in the form of bonuses (double exp, faster earning of money, whatever), or in the form of tangibles such as weapons or stronger characters. The most obvious one is the current games whereby you establish a limit on 'turns.' Those turns govern your advancement, access, worth... the person with money can move infinitely, the one without sits and waits. By the end of the week, they have no competition.

The goal in both is to make money. That is the business and that will always be business. The harm, is that its no longer a playing field where you're playing a game. Its buying the win. Since the business model works (they profit, who cares about the person?) the gaming industry shifts so that it continue to make that profit. Thus, you have DLC - the game is incomplete the first time you pay for it, so to play it you have to buy the rest. Though, you don't have to. But, an entire ecosystem is playing the cooler stuff... and you're sitting behind.

This business model is new. The reason its different from TCG, is TCG itself requires a tangible asset - you cannot play without the cards. Magic is nothing without a deck. To build a deck you must buy the cards. Invariably this means that to build a good deck, you must increase your chances to obtain a valuable card - thus you need to buy many boosters and decks. The model itself is simple, but its not exactly able to be changed - if cards are merely an imaginary item that one draws on their own, then the deck is never different. It reduces the unexpected and you remove the need for that extra bit of strategy. The ability to build a good deck is not necessarily tied to value, only the chance is increased the more you buy. The chance is always there - its never a zero value. In the pay to play games, the value is always tied to your success: there is no chance to your "strength" it is only your stats, items, level, money... whatever.

A good example of the difference is to compare it to a similar platform. There is a game in the app store(s) called Age of Warring Empires. It's your typical "build a city" "get 'cards' of various strengths representing characters' 'level them, build armies, attack others.' Well, every single one of those things has two ways of advancement: money or time. There is no way to get the best items without spending money. None. The only way to win, IS to buy the win. In magic, sure you have to buy the deck... but for all intents and purposes, there is a non-zero chance that first box you get builds a deck worth winning.

</comment><comment><USER8> I never played trading card games... I even had to look up what TCG meant. So, I'm not the best to suggest why they were better accepted. But if I had to guess, it was that everyone one had a shot at getting the best cards. Even if you only had one or two packs, you could have gotten a super rare card. If you had a hundred packs, you still may not have gotten the "golden ticket". So, money didn't necessarily correlate 1:1 with advantage.

In games like Clash of Clans, etc... You can play without paying. But it is just depressing to have an opponent attack you, where you can tell that they have effectively bought their way in. They didn't spend the time to effectively build their city, wait for their upgrades, etc... instead, they just bought a ton of gems and used that to make their city.

So, the users who don't just buy their way can feel cheated by the game. They put in a lot of time into their cities, but they can just get crushed by people who just bought theirs.

Sure, the authors can get more money, but it just ruins game play for the rest of us. Even in games like Candy Crush - you _can_ win without paying extra, but for some levels it's almost impossible to complete without using bonuses.

Source: I've played both Candy Crush and Clash of Clans to the point where they weren't fun anymore largely because of the pay-to-play nature.

<comment><USER6> > In games like Clash of Clans, etc... You can play without paying. But it is > just depressing to have an opponent attack you, where you can tell that they > have effectively bought their way in. They didn't spend the time to > effectively build their city, wait for their upgrades, etc... instead, they > just bought a ton of gems and used that to make their city.

I don't really see the problem there. It's no different from players who simply got in earlier and got a head start. Games where some people join later are unavoidably going to have these kind of inequalities. To me, it doesn't matter if someone is stronger because he played longer, or because he bought his way in.

But if he bought his way in, he's probably less experienced than his strength suggests, and I might be able to defeat him despite his theoretical strength.

And MtG is far more evil in this regard. That one rare card in every pack is exactly meant to drive addiction, and get people to pay one more pack hoping for the rare card they want. In a way, MtG pioneered the pay-to-win game play, and plenty of people resent it for that reason. Though, in its defense, Magic's success may have been an accident; they may not have been intentionally taking advantage of addiction, and many of these modern mobile game companies definitely are.

But the main difference is that in the end, Magic is fun. If you just play opponents with a similarly limited collection, playing with less cards may actually be more fun than having everything. But many of these mobile games are intentionally designed to be less fun, to have lots of micromanagement and tedium with very little actual game underneath, and you can pay to skip the boring game play.

<comment><USER8> I guess the difference is that in some games, you are pitted against other players at the same "experience" level - to level the playing field. So that very experienced players aren't able to just kill all the new players immediately. However, if you have a player that has bought their way in, they will have a low experience level, but resources that are better matched against higher levels. So, if you don't buy in, you will be at a severe disadvantage.

</comment></comment></comment><comment><USER9> It's entirely a matter of how the user is introduced to spending money in the game.

Trading card games require an initial purchase - most people purchasing them are aware of what they're getting themselves into. You know there are lots of rare cards that you'll never see, and you're fine with that when you buy your deck(s). For one thing, this filters out a lot of people who would gripe about having to pay. But also, if you play enough to really need the best cards, usually you've accumulated enough cards that you can trade with people to make any deck you want. This places a sort of spending cap on the game, after which you can compete with the best players in the world - which can be a pleasant surprise to players who haven't thought that far ahead.

Modern free-to-play games start out free, then surprise users with ways to spend money in the middle of the game. As you play on, even if you do pay, you discover that there is no limit to the amount you can spend - and you see that there will always be better, more powerful users who have spent more than you. Lots of users become bitter about this once they've invested some amount of time (and/or money) in the game world.

</comment><comment><USER10> My problem is that games can now no longer ask for an honest price upfront and not use manipulative tactics to extort extra money from players.

A car racing game should be advertised at $X, with DLC like extra tracks or cars being available for more money.

But manipulative tactics mean the player will be forced to grind a single track many times to get something that allows them to continue. They can pay to avoid that grind. Worse artificial delays are often built in and an IAP is provided to circumvent that artificial delay. Using our hypothetical race game as an example there might be a supply of tyres. Each time you enter a race you use four tyres. Tyres are replenished at a rate of one every hour, unless you've paid for an IAP - "tyre factory upgrade: never run out of tyres - $Y".

EDIT: plenty of people have bad memories of collectible card games and talk of feeling manipulated and exploited and addicted.

</comment><comment><USER11> Let's talk about Team Fortress 2, Valve's first big F2P game.

The model is this: If you play for long enough, you'll receive new equippable weapons at random times. You can trade these with other players, craft them together to create different items, or simply buy them with real money. So far so standard.

What's interesting is that the non-default weapons are all balanced against each other. In theory, players who grinded for a long time or paid real money are still on an equal footing with players who joined the game yesterday - actual skill at the game notwithstanding. In practice, mistakes are made (the Soldier's default melee weapon is a lot weaker than all the available alternates, although the alternates are all roughly equal in power), but the idea is there.

And there are items that can only be earned through the shop, or as part of one-time giveaways, or by earning achievements in different games. But all of those are either completely useless (hats and badges), or cosmetic variations on existing items. Their value is not that they make the player stronger, but they simply tell other players "I have something you don't have".

TF2 demonstrates that pay-to-play can be done right. It's simply a matter of striking the balance between creating something that lots of people will play and creating something that earns a lot of money per player. Unfortunately, in the mobile world, 10 mediocre apps are a lot more profitable than 1 excellent app, so there's little incentive to create quality. That's the real problem, not pay-to-play.

</comment><comment><USER12> This is an interesting discussion, but no one has mentioned the physical aspect of trading card games.

When you purchase a pack of cards, you now own them; you can hold them in your hands, arrange them in binders, sell them on to someone else, etc.

With free to play games, you buy some gems or coins and then spend them in the game and they are gone! You can't sell them on, you cannot take them out again later and look at them. It feels more like burning money than buying something.

</comment><comment><USER13> Before seeking explanation, I would suggest defining what one means by _ruining_.

</comment><comment><USER14> I think a lot of commentators expect from a f2p game to behave like a pay upfront game. Game and bizmodel need to be in sync. Both models have game designs that work better in the respectable monetization model. F.e. Payupfront games usually have flashy graphics. F2P often use tcg mechanics.

I wonder why you would like to pay up front for a promise rather than trying to play a game for free and if and only if you think it is worth it pay some money.

I believe we can all vote with our money which model we believe is best. Let the market forces figure out which model will be dominant in the next ten years.

</comment><comment><USER15> Ruin the industry ? No, but it changed the industry nonetheless. Imo most pay- to-play games aren't really games in the truest sense of gaming. A game like Clash of Clans or Candy Crush is played by millions but would it do well in a real game review ? Is it real fun at the core to entertain gamers ? No, because those games are more like playable advertising entertainment than real games. There's a place for both though and some pay-to-play games are worse than others.

</comment><comment><USER16> There's a _huge_ difference between the TCGs of old and the modern freemium games. TCG is part gambling, part gameplay, and even the gambling is optional with preconstructed decks (Magic the Gathering in particular has pushed premade decks recently with their Duel Decks series of produces). Freemium games, however, are _entirely designed_ to exploit human psychology to nudge their users to spend money.

<comment><AUTHOR> But do they not both operate on the same business model? IMHO I think you are giving TCGs too much credit. Yes, they have far more lore and real playing time, but strategy can only take you so far as a player. That plus the random nature(or gambling as you put it) of the packs only further adds excitement and ultimately, addiction.

<comment><USER17> I've always maintained that the moronic land/mana system in MtG was designed to facilitate their business model. The increased randomness it introduces obfuscates their pay-to-win design.

<comment><USER2> Not by design. TCGs didn't really exist before MtG, they stumbled into a successful business model.

<comment><USER11> Originally, yes, but it's been two decades since Alpha. I think by now they have a pretty good idea of what they're doing and why it works.

</comment></comment></comment></comment></comment><comment><USER18> I dont know current state of things, so I speak in past tense. MTG was very balanced. Every uber-card had uber-cost and needed proper protection. Also, there was a cap on number of same cards in your deck. So you couldn't extensively abuse mid-power cards too. As a result, you can counter expensive deck by not so expensive one. Game was in most parts about proper tactics, not deck.

</comment><comment><USER19> The biggest problem is that these games are categorized as free in app stores. This is false advertising.

A new category (maybe called "freemium") needs to be set up for games like these, so we can avoid them wholesale.</comment>


Ask HN: Alternative to Google Docs/Drive? - <AUTHOR>

What is your free alternative to Google Docs/Drive?<p>Main reason is security, and curious as to alternatives. <comment><USER2> Dropbox , Mega.co.nz , Copy.com ...

edit : sorry I mis-read your question. I think you're asking for drive space with ability to edit docs on the drive itself right ?

one-drive does that, but if you're concerned about security maybe you get a server and install microsoft office webapp server 2013.

<comment><AUTHOR> Yes looking at editing docs

</comment></comment><comment><USER3> Hackpad?</comment>


Show HN: My Project Management and (eventual) Collaboration Tool (Server down) - <AUTHOR> http://www.thetaboard.com

<comment><AUTHOR> Hey everyone. I've been working on and off on this for the last 9 months or so (god has it been that long). I wanted to learn backbone.js, improve my javascript skills, and build a tool that I felt had been missing. So I build ThetaBoard--a (very) simple tool for managing lists and projects.

Unfortunately, Trello came out in September and was fairly similar to my original vision. I thought about stopping development but my vision for ThetaBoard is a bit different than Trello so decided to atleast get an MVP out there and see what people thought. Would love to hear your suggestions and ideas. Especially any areas where tools like Trello aren't really scratching your itch.

</comment><comment><USER5> Just had a play. Looks good. A few comments:

      - <USER2>
      - Switch the screenshot and demo button around (button on right)
      - Improve the quality of the screenshot
      - Pre-fill the blank slate with some demo items
      - Allow users to download data (json/xml etc.)

      - <USER3>
      - When using the demo, press save, then [browser back]. I get a JSON representation

      - <USER4>
      - Does it allow multi-user access?

Keep it up.

<comment><AUTHOR> Thanks a ton. I put the landing page together last night and I'm not much of a designer (tho was pretty happy with how it turned out). Definitely needs better screenshots (and it doesn't work on the ipad right now so should probably drop it!)

Data export coming! and yeah, I prepopulate the initial board with some default columns but should throw a couple stories in there.

It doesn't currently allow multi-user access but it's (fairly) useless without it long term. The free/personal plan isn't collaborative (that's my initial plan). When/if I add some premium plans it will obviously have to have multi- user and realtime updates.

Thanks.

</comment></comment><comment><USER6> I like this. I do have some comments:

      - When dragging from one board to another, unless I drag to the right location, I can't drop. It would be nice if I could drop anywhere in the board
      - Keyboard shortcuts?
      - A way to save a story without using the mouse
      - If I drag from the To Do board, I can drag (forever) to the right. This isn't a problem, per se, but is definitely unexpected behavior.

<comment><AUTHOR>
       * I think I just need to add some padding into the jquery.ui.sortable to make them more "accomodating"
       * Thanks. I had some simple keyboard shortcuts in place (ctrl+n, ctrl+s) but found a couple of bugs in the library so temporarily removed them.
       * Saving without a mouse: hitting tab currently should do it but keyboard shortcuts coming soon.
       * Yep, hadn't noticed that it flies off to the right. Thanks!

</comment></comment><comment><USER7> I like it. Solving Project Management pains is hard. There are way too many tools that don't work. I like your approach - having a very fast interface to add and move items makes a significant different.

That being said, how do you intend to be different from Trello?

<comment><AUTHOR> Thanks! One of the things I'm trying to do design wise is eliminate/minimize pop up screens and multiple pages, etc. I want everything to accessible from one screen.

My plan is to add functionality--initially realtime collaboration--and then comments, tasks, assigned users, point/time tracking, etc. but make all of the features opt-in and customizable.

I consider this the real minimum viable product. Just a list of items. Priority represented by position in a list. Status respresented by WHICH list. An unobtrusive backlog. An accessible archive. I want people to be able to use it at this level of simplicity a year from now.

<comment><USER7> Those sound really good - but aren't they exactly what Trello is already doing?

<comment><AUTHOR> Trello is a great product and, honestly, it was a bit deflating when they launched. Not to mention they are (currently) free and I hope to offer premium packages.

The one (only?) thing about Trello that I don't love is the number of pop up screens, etc. I want ThetaBoard to be a single interface where you can do what you need from the one page. If that makes any sense.

<comment><USER8> I really like your product, and I also like Trello, but unfortunately our corporate policy is to avoid hosting data on third party servers so I can't use either. These products would make a great tool for my small team.

This is not a suggestion just a comment/wish, I'd like to see some app like yours offer the ability to store/retrieve data from a web service that we can provide to you but written to your specification, not sure if something like that is possible, but it would be preferable to a packaged application my small team cannot afford. I haven't seen a SaaS app take this approach, but it is interesting to think how it might work. UI as a Service?

<comment><AUTHOR> Really interesting idea. With Backbone.js and RESTful APIs (which ThetaBoard is using), it wouldn't be too difficult to implement on the UI side. The hardpart would be getting organizations like yours to build their own public api exposing their business data.

</comment></comment></comment></comment></comment></comment><comment><USER9> Looks nice! My suggestions;

Keyboard shortcuts (N for new to-do, Shift-S for saving item). An API, or a Mac/Win app or terminal tool.

<comment><AUTHOR> Good ideas. Probably go API first...

</comment></comment><comment><AUTHOR> Any way to change a title of a post after 2.5 hours? Wouldn't mind removing the "(Server Down)" part... If anyone (pg, moderator of some sort) wants to help, the original was:

Show HN: My Project Management and (eventual) Collaboration Tool :: Θ ThetaBoard

</comment><comment><USER10> Using a column name as "<script>alert(1)</script>" I get an error.

<comment><AUTHOR> I think I'm glad.

</comment></comment><comment><AUTHOR> Ouch. Server swamped. Rookie mistake. Resizing it to a bigger instance. Check back soon!

</comment><comment><USER11> Does not load here.

<comment><AUTHOR> Yeah. I _thought_ I had resized the server instance last night but it looks like it failed. So it's now running on a 256MB instance... on w/ support. Check back soon!

<comment><USER11> Works now. Interesting. Are there any hotkeys? I think it would be nice to move an item via Ctrl + left. Also some colors for priorities..?

<comment><AUTHOR> Hey. I had a few basic hotkeys in place this morning but found a bug so dropped them out of the build (ctrl+n for new, ctrl+s for save). Want to get the hotkeys right so going to give them some more thought before I implement them.

Planning on implementing colored tags very soon...

</comment></comment></comment></comment><comment><USER12> very nice, intuitive and simple. I love to use it.</comment>


Ask HN: How to manage a team of clowns when you are a young 19yo manager? - <AUTHOR> I am working at a huge corporation. I just turned 19. I am part of a small team working on mobile applications (about 40~ people total). I was hired at the highest pay grade right out of college after 1 year and given a team because I impressed execs.
Since I'm 19, people disregard me. I'm the office "wonderkid" and people frown upon anything I say on account of being a smartass, however hard I try to come across as genuine. I am not taken seriously, however, nobody can deny the work I do is great and beneficial. I've upgraded out tech stack, introduced new methodologies, new tactics, that have increased our efficiency near ten-fold. However, there are a plethora of teams under my project, and they only want paychecks, they don't care, they just need to support their family. And I get that. I do, but if you're put on such a high profile project, you need the best. There are better departments suited for their mentality.
If I'm to speak frankly, 80% of this team could be let go and we'd be much more efficient, things would run a lot smoother. These teams are bogging us down by not meeting deadlines and producing shit work. They don't interact with the rest of the team. Nobody cares, just want to get paid.
I can't attach my name to something I feel doesn't encompass every fiber of my talent and skill, and it's making me angry.
I literally created a working demo of our app with over 120+ screens in three days. Asked my manager if I could work from home. Didn't sleep, created it, pitched it to all managers and everyone. They genuinely loved it.
But at the end of the day, it can't pass because it'd put 80% of our team out of their jobs. And that's the problem. There is no passion in our team, deadlines and shit members are destroying this project and thus, morale is down and I'm not remotely motivated anymore to make this the best I can make it.
What do I do? <comment><USER2> 1\. You don't have enough life experience to relate to anyone working for you, let alone to have them imagine they could relate to you in response. Respect and trust is something you have to earn; it doesn't just come from the title. You're currently lacking in about ten years of empathy and "soft skills." Management should be 100% about people skills and 0% about getting your name on something. Maybe you weren't given this team because you're awesome; maybe you were given it because it would knock the chip off your shoulder and take you down a peg.

2\. Go pick up rands' book, Managing Humans. Read it. Try to understand your actual purpose in running that team. Then, either:

3a. Quit. Go work somewhere where you'll be mentored and taught all of the things you never learned in school. Relationship-building. Being nice and personable. Negotiation. Communication. You'll learn amazing things.

3b. Fire people. If you're really a manager, you have hire/fire power. Fire the 80% you think suck. Push your project live. Become a terrible, powerful figure. Set fire to everything in your path. You'll learn amazing things that way, too.

<comment><AUTHOR> 1\. I was given this team right off the bat, I've been here for a few months now. It's not to take me down a peg. I had a great portfolio and track record in this industry, however young, and they believed I can do it. I didn't get here without being a people person ;)

I am so uncomfortable with 3b, but if that's what needs to be done..

What if they can't find a job? What if they lose their houses/apartments? It can seriously screw some people and I can't have someones life situation resting on my shoulders because they failed to do a great job.

<comment><USER2> Hi, sorry, I think this is really jumping the gun, and this is going to sound like a personal attack, but I'm not sure there's another way to phrase any of this.

The way you've described the problem, the way you've classified your coworkers, the things you called out to comment on in this reply, these are all giant red flags of immaturity to me.

I ran companies and teams of half a dozen to three dozen people when I was your age (and younger, and older), and I hired people, and I fired people, and you sound like me, and I was grossly immature.

If you've only been there a few months, it takes 3-4 months just to get a feel for the job. If you haven't been networking and talking with everyone above and below you, and instead your head has been down grinding on some possibly pointless deliverables, you don't know _anything_ about your role or your company yet.

You don't know why your coworkers are the way they are. You don't know why you were hired. You don't know the real expectations for you _from your employees_. And you don't know what kind of a manager you are, because you have no experience being managed.

You need to read rands' book, and then quit, and go work for a less immature company until you yourself are less immature. Management is a skill you don't have yet, and can't possibly get without making a lot of terrible errors in your current role.

<comment><AUTHOR> You are making an incredible amount of assumptions.

We were all hired at the same time. Everybody is new, but not new to the field, we got to work from day 1. We are hired for very specific tasks, we get in, we get out, and right now we're not getting in fast enough. Make sense?

I know the way they are, I know why they were hired. It doesn't matter what their expectations are from me, because it's below what I'm capable of getting accomplished and that's not the game I play. Don't get me wrong, we're all friends. It's not me vs. my employees. It's an internal struggle of mine to get my teammates to properly match my level of expectations, not just make something passable that hapazardly works.

We are a team of contractors here to get a job done, and it's not being done as best can be.

I work for one of the biggest companies in the US. There's a high probability you use one of our applications.

We all work in a common space. When one co worker is on the phone with their tenant and divorce lawyer on and off all the time, then complaining about hitting deadlines and not meeting them, we have a big fucking problem.

I know what I'm dealing with, thank you for your input. What I'm having a hard time with is determining the route to solve this problem without ruining lives.

<comment><USER2> Oh, okay, cool. In that case...

Just kidding, that doesn't change my core premise, that it's an immature organization and you're dealing with the problem in an immature fashion.

 _" It's an internal struggle of mine to get my teammates to properly match my level of expectations, not just make something passable that hapazardly works."_

That's the problem, right there. Your expectations are yours and yours alone. Everyone under you is a person, a human being, with thoughts and feelings and goals and, rightfully, they don't give two shits about what you think they should be doing. Real life is not a meritocracy and everyone is not a highly disciplined type A producer. Your expectations are your problem, not theirs, and holding other people up to them is the express route to disappointmenttown, population: a bad version of you.

You need to understand what it means to be a manager, and an empathetic human being.

Pro tip: those are mostly the same thing.

Maybe you will need to separate the wheat from the chaff one day, but that day is after you understand exactly what it is all those people do, and why they do it, and how they do it, and what their goals are, and what their motivations are, not as employees, not as cogs in your great machine, but as _human beings._

That day is not today. You don't know enough, and it's not possible for you know enough yet. You haven't been doing the job long enough, you don't know the people well enough, and you don't have enough life experience.

<comment><AUTHOR> Did you read my other responses? You are here at this company and are being paid exorbitant amounts for the 7 hours you are here every day. That time is not to goof off and take two hour lunches, then complain about missing deadlines _that I didn 't set_.

If you want to say something, then say something instead of spouting bullshit. I'm dealing with a tough fucking situation and I didn't come here to get shitted on by a 1 upping random (really, you were younger than 19 working at a fortune 500 managing 40 people, okay kid).

Really, if you want to offer proper advice other than "you're a piece of shit" (to summarize) then fuck off. I came to ask HN because it's a professional community with people that have a diverse range of skills in these very environments I'm struggling with.

Stop replying, you are stressing me the fuck out, thank you.

</comment></comment></comment></comment></comment></comment><comment><USER3> If you're going to get people fired and don't meet the deadlines. You're going to get screwed either way.

Try to get the worst 20% off and give the top 5% a payraise, use gamification techniques. I don't know if something like that exists.

But their's a reward for doing good and a punishment for doing this bad. Most people will understand, except the once who get fired.

Slow people bring you down, good people bring you up. Motivate them, so you'll get motivated to.

PS. 120+ screens is really impressive!

<comment><AUTHOR> Thank you.

It's less impressive when you realize that it's just designing a handful of reusable styled html assets, arranging them per page, then linking them to another page.

</comment></comment><comment><USER4> I can certainly identify with being a younger guy in a large corporation and never getting taken seriously. That dynamic is the root of startup culture, typified by ycombinator - since young people frequently are talented enough to run a company, they might as make the opportunities for themselves. I think the choice is to leave or to make the most of it - and if you have the authority to reshape your team, you should do it.

</comment><comment><USER5> you should quit and go work at a smaller company.</comment>


How to zero a buffer - <AUTHOR> http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html <comment><USER2> Slightly OT since it has little to do with security, but fighting the optimizer is something FPGA Verilog and VHDL designers must also master.

If you don't use an the result of some logic it will be optimized out. One way to prevent this is to route it to a pin.

If logic is fed by a constant, it will be optimized out right up to the point where the result of the logic is mixed with some external input. (early tools could not use the dedicated reset net due to this- reset for each flip-flop had to be routed to a pin or the reset net was optimized out which means the initial state of your flip-flop is lost).

If you have identical logic, one copy is optimized out due to aggressive CSE. This is often bad for performance (routing in an FPGA is as slow as logic, so it's better to regenerate identical results in multiple places), so you add "syn_maxfan" constraints to prevent the "optimization".

On the other hand, an input flip flop will be duplicated if the fanout limit is exceeded- but this prevents the use of the dedicated I/O cell flip flop which then causes external timing to be messed up. So you use syn_maxfan=infinite for this case.

<comment><USER3> Why would you want your FPGA to have circuits that aren't used? And why don't you want constant expressions to be pre-calculated by the optimizer?

<comment><USER4> I have the exact same question.

I presume this is for some incremental development work. Like testing and seeing the number of gates/pins used for a design but you need to feed the logic with constant placeholders.

</comment></comment></comment><comment><USER5> Can someone explain this line:

          static void * (* const volatile memset_ptr)(void *, int, size_t) = memset;

I've written some C but that is utter gibberish to me.

<comment><USER6> As usually in C, you start from the name, then try to go to the right until you hit parenthesis, then go to the left until parenthesis, rinse and repeat.

So, first, the name:

        memset_ptr

Then, try going to the right, but aha! before we can really gain speed, a parenthesis is immediately blocking us. We shrug off the bruises and turn to the left:

        (* const volatile memset_ptr)

_" Hey guys, memset_ptr is a volatile const pointer..."_ Now, we hit left parenthesis, so we're again allowed to go right, yay!...

        (* const volatile memset_ptr)(void *, int, size_t)

_"...to a function taking such-and-such arguments..."_ Uh, oh, the equal sign, so no more to read to the right; disappointed, we turn back to the left for the final run:

        static void * (* const volatile memset_ptr)(void *, int, size_t)

_"...returning a pointer to void! Hah, got you! Simple, really. No arrays, no pointers to pointers, not even a function pointer returning a function pointer, meh. Uh, oh, aaaaand, yes, by the way, the variable is static, so, like, file-local, um. Yeah, yeah, I saw it from the beginning, oh, go away, you're just picky. And, and, you wouldn't recognize a function returning a pointer to an array of pointers to functions returning anonymous struct even if it hit you in the face, pfff!"_

<comment><USER7> Is "void *" really something you can pass?

<comment><USER8> Yes, it refers to a memory location, without implying anything about the semantics of the bits located at that location. You can't dereference or assign to the location because you don't know the type at that location. You can however assign that pointer to a typed pointer variable to actually read or write to that memory location. This is useful when you really care about the bits of memory but you're variable pointing to that memory could just as well be an (int64_t _) as a (char_ ) and those types are not interchangeable with each other, only with (void _). So library functions that just care about memory locations, not the semantics of the bits there, take (void_ ).

Some of this may be technically incorrect. This is my own mental model of the C language which is sometimes incomplete.

<comment><USER7> Hmm, I'm a bit confused. Isn't that a function call, rather than a function declaration? If it's a function call, it's passing a bunch of types in, which I thought was not valid C?

<comment><USER6> Ah, now I get your question. So, it _is_ a function declaration, _not_ a function call. Um, sorry: a declaration of a _pointer_ to a function, where this function would take as arguments: some (unnamed) void pointer, some (unnamed) int value, and some (unnamed) size_t value; and would return a void pointer.

Um; then there's the equal sign, so this is not only a declaration, but a definition too; but _definitely_ not a call.

A _call_ is further down in the original blogpost, in the below line:

        (memset_ptr)(p, 0, len);

<comment><USER7> Oh! A pointer to a _function_! Aha, I didn't know that was valid, thanks!

</comment></comment></comment></comment></comment></comment></comment><comment><USER9> In GNU C one can add the statement

        asm ("" : : "m" (&key));

just before or after the memset, effectively telling the compiler that the address of "key" escapes the scope of the function.

<comment><USER10> GCC also has an `optimize' function attribute which might make sense to use here. This can set optimizations for the function to -O0. But I haven't tried it.

<comment><USER11> That's not enough, since even -O0 applies a few optimizations, and which optimizations it applies could change in the future.

The best answer is really GCC's __asm__("" : : "m" (&key)), or perhaps something like __asm__("" : : "r" (key) : "memory"), after the memset. It generates no extra code, just ensures that the memset won't be removed.

For other compilers (in practice only MSVC, since clang is gcc-compatible), you could pass the pointer to a dummy assembly function instead of using inline assembly; even link-time optimization can't know what happens within a function written in assembly. Or, for better performance, create in assembly a "safer_memset" which is a single instruction: a jump to the real memset function.

</comment></comment></comment><comment><USER12> When this still doesn't work: JIT compiled C. The compiler can check for memset and elide it. (Or hell, one can envision the hypothetical Antagonizer9000 compiler including a version of memset which peeks up the stack to see what it's clearing and stops short.)

<comment><USER13> To clarify: the strategy in the post doesn't actually work (or at least, is not guaranteed to work in every conforming implementation): the "volatile" only applies to the read of the function pointer, _not_ to the execution of the function in question.

You don't even need to assume some sort of crazy evil compiler to have to worry about this - speculative inlining of function pointers guarded by a safety check is something that FDO builds will actually do.

<comment><USER14> The first comment there (by Anonymous) claims that the final technique can also be optimized:

        (memset_ptr)(p, 0, len);

_> can be replaced by:_

        if (memset_ptr == memset) {
            memset(p, 0, len);
        } else {
            memset_ptr(p, 0, len);
        }

_> Which in turn can be optimized using the other tricks noticed above into:_

        if (memset_ptr != memset) {
            memset_ptr(p, 0, len);
        }

I'm no expert, but this seems like a believable defeat of the technique in the post.

<comment><AUTHOR> That's not quite right since it's now reading memset_ptr twice, but the concept does seem to be right -- the volatile pointer must be read but the standard doesn't require that the function is invoked.

<comment><USER15> What about a data race? Theoretically, the function that memset_ptr points to could be changed between when it is checked and when it would be run.

<comment><USER16> If you have multiple threads accessing a shared (mutable) variable in your program, even a shared volatile variable, then you need to guard _every_ access to that variable (which, in this case, includes every function call through memset_ptr) with proper thread synchronisation primitives. Marking a variable "volatile" is not enough to prevent data races in a multi-threaded environment.

If you've put a semaphore, or mutex lock, or whatever around your calls through memset_ptr(), the transformations will all take place inside the lock, and data races should not be an issue.

<comment><USER15> I think you missed my point.

memset_ptr is a const (not changed by this program... theoretically) volatile (allowed to be changed by the system, theoretically) pointer to memset. In THIS PARTICULAR CASE, memset_ptr points to memset. The compiler however doesn't know that it won't change due to another processes, but we do. So the compiler shouldn't be able to optimize out the call directly to the function pointer because it introduces a possible race condition: the program reads that memset_ptr points to memset, then the pointer changes (due to some other process changing it), but the program still calls memset, and not memset_ptr. The optimization allows for a possible race condition to occur.

<comment><USER12> That race exists regardless. Many systems will execute this as loading the pointer into a register, them jumping to it. The value could change between those two instructions.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER17> Is the proposed solution really the best approach? It seems complicated to me and relies on obscure parts of the language. Maybe the problem (compiler optimizes away function call because the result is no longer needed) could be solved like this:

      memset(key, 0, sizeof(key));
      if (key[0])  // we are using key, so you can't skip memset()
        dropDead();

Unless the compilers "understand" memset and still optimize away the last two lines? I would hope not... Does anyone know how aggressive the C optimizers are these days?

<comment><USER18> > Unless the compilers "understand" memset and still optimize away the last > two lines

They do. That's the whole "problem" \- the compiler knows what memset is and what it does, since it's specified in the standard.

</comment></comment><comment><USER19> Why wouldn't you make key volatile? Shouldn't that solve all the problems? Or is it because it would be to slow because the compiler can't do that many optimizations in the rest of the function any more?

<comment><AUTHOR> Yes, making _key_ volatile would force the zeroing to happen; and yes, you don't want to do that because it would absolutely kill your code performance.

<comment><USER20> Can't you just cast it to a `volatile uint8_t *` at some later point when you need to ensure that we've zeroed the memory?

<comment><USER21> That's discussed in the article. Volatile ultimately applies to the storage, so a sufficiently smart compiler may be able to deduce that you're lying to it with the cast and elide the write.

</comment></comment></comment></comment><comment><USER22> _While this completely subverts our intention, it is perfectly legal: The observable behaviour of the program is unchanged by the optimization._

This begs the question of what is "observable behaviour" \- execution time, which is definitely "observable" and the basis of timing-based attacks, can certainly change depending on what the optimiser decides to do.

I think this and similar cases of "fighting the optimiser" should really be solved with per-function (or even per-statement) optimisation settings; both GCC and MSVC support #pragma's to do this, although it's nonstandard.

<comment><AUTHOR> The term "observable behaviour" is defined in the standard: Essentially, I/O to files and interactive devices, plus accesses to volatile objects.

<comment><USER23> Perhaps in retrospect this was an inappropriate choice of definition, at least for cryptographic operations.

<comment><USER24> I'm gonna go ahead and say it: Perhaps in retrospect C is an inappropriate choice of language for these kinds of applications.

This "Performance at all costs, including safety and predictability" thing may be appropriate in video games, but for security-critical applications that philosophy is downright negligent.

<comment><USER12> I'm not aware of any language that would be better. Most languages don't even let you touch memory to try to zero it.

<comment><USER25> Many languages zero every allocation unless they can prove that you immediately write over that memory without reading it.

<comment><USER12> Which does nothing for memory which has been freed but not reallocated.

<comment><USER25> That's a great point; should've thought through that post a little better. Thanks.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER26> Why would you want to zero a buffer ? Because it may contain sensitive information, I presume. If you don't have additional properties w.r.t allocated memory, what prevent a system with high load to temporarily put the given memory block on swap, leaking the information on disk ? Security is hard...

<comment><USER27> >Why would you want to zero a buffer ? Because it may contain sensitive information, I presume.

You don't zero sensitive buffers. You randomize them, then free() them.

<comment><USER28> Why do you randomize them?

<comment><USER29> Because just free()ing them means anyone calling malloc() can get your password.

<comment><USER28> So why don't you zero them?

<comment><USER27> Because then your attacker knows that your buffer had something in it of value.

</comment></comment></comment></comment></comment></comment><comment><USER30> Interesting. This appears to solve a more general problem, which is: how to create a barrier against inter-procedural optimization and dead code elimination.

I wonder if this trick could also be used to solve the double-checked locking problem.

From the quintessential DCLP paper ([http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf](http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf)):

        Consider again the line that initializes pInstance:

        pInstance = new Singleton;

        This statement causes three things to happen:
        Step 1: Allocate memory to hold a Singleton object.
        Step 2: Construct a Singleton object in the allocated memory.
        Step 3: Make pInstance point to the allocated memory.

        [...]

        DCLP will work only if steps 1 and 2 are completed before
        step 3 is performed, but *there is no way to express this
        constraint in C or C++*.

But Colin's pattern here seems to be a way of indeed guaranteeing this. The volatile function pointer is a barrier against inter-procedural optimization: if the function must be called, then step 3 cannot possibly be performed before steps 1 and 2.

(There might still be necessary hardware barriers that are missing, and the lack of a memory model for pre-C11/C++11 probably makes it all technically undefined behavior anyway. But the key sequential ordering constraint that was claimed inexpressible in C and C++ appears to indeed be expressible with this trick, if indeed the trick works for guaranteeing a call to memset).

<comment><USER31> _if the function must be called, then step 3 cannot possibly be performed before steps 1 and 2._

So just to clarify, there's no way the compiler could do "1, 3, 2" instead of "1, 2, 3"? It seems a naive implementation of a compiler could store the pointer to the allocated memory in the pInstance variable before calling the constructor, rather than using a temporary location for the pointer (e.g. a register). Does C++11 and later specify otherwise?

<comment><USER30> I should have been more specific. To use Colin's trick with this pattern, you would need to write a separate function (like InitializeSingleton()) that calls the constructor and returns the pointer. If InitializeSingleton() is impossible to inline/optimize, which is the goal of Colin's trick, then 1 and 2 must happen before 3, because 3 cannot happen until the function has been called and returns, and the function does steps 1 and 2.

</comment></comment></comment><comment><USER32> You should have test cases to verify the zeroing behavior in the object code. Even if the standard says a compiler must do something does not mean that it does.

<comment><USER33> The difficult thing is that any way to verify the zeroing behavior would change the compiler's decision about whether it could elide the call to memset. So it's possible (well, almost guaranteed) that the test would succeed even though the memory wouldn't actually be zeroed in production.

<comment><USER34> If you set up your tests up correctly they should test the exact binary or shared library that is deployed to production and not some test-specific build.

</comment></comment></comment><comment><USER35> At least in LLVM 3.4, this seems to do the trick too:

      static void secure_memset(void *, int, size_t) __attribute__((weakref("memset")));

</comment><comment><USER36> Nice teaser at the end there. Does it have something to do with the fact that the OS may have paged the memory containing the sensitive data to disk?

<comment><USER37> I figured the article would be about how you have to write random data to the buffer to truly "zero" it, otherwise the ghost of the data can still be read using some trick.

<comment><USER38> Main memory decays in milliseconds.

</comment></comment></comment><comment><USER39> This all seems kind of silly. Why doesn't C have a type qualifier like called "secure" to inform the compiler that it should avoid security-compromising optimisations and maybe even automatically zero the memory when it falls out of scope?

<comment><USER40> That sounds a lot like automatic memory management!

To a C dev, that's the same as communism to a US Republican.

<comment><USER41> As a C dev, no. First, stack allocation is a type of "automatic memory management", and in most situations we C devs are perfectly comfortable with it. Second, in terms of how the memory is allocated/deallocated, the above doesn't sound any different than stack allocation. The difference is more like "volatile", telling the compiler "this memory is special, treat it carefully", and it mostly doesn't seem unreasonable. Note that C compilers frequently have extensions providing a way of naming destructors for particular variables. It probably _would_ still be possible to skip it with a non-local jump (longjmp or computed goto) but avoiding those in security conscious code is probably _already_ standard - it basically is in most code I've encountered.

</comment></comment></comment><comment><USER42> Colin, you're missing end-parenthesis in your memset calls.

<comment><AUTHOR> Fixed, thanks.

</comment></comment><comment><USER43> It is a little mind boggling that support for proper handling of this didn't arrive until c11. For a symmetric cipher without a demanding setup/init phase - would it make sense to just do a few rounds on a buffer using the zeroed key? Obviously quite a few more cycles, but should at least be a predictable (constant) overhead?

<comment><USER33> What do you mean? The solution that Percival presents compiles fine on my C89 compiler.

<comment><USER43> I didn't mean to imply that the solution as presented didn't work, I was just wondering if it would _also_ work simply running the cipher with the zeroed key in order to avoid zeroing the key being optimized away. Obviously that'd be a lot more cycles; I'm just curious if it would be a viable solution ;-)

<comment><USER33> I was referring to the first sentence ("It is a little mind boggling that support for proper handling of this didn't arrive until c11."). I don't see anything C11-specific in the code Percival posted. I don't know enough to say anything useful about the rest of your comment.

<comment><USER43> My point was that this dance around "observed behaviour" isn't needed in C11, as per: "(...) on C11 (are there any fully C11-compliant platforms yet?) you can use the memset_s function. (...) [which is] guaranteed (or at least specified) to write the provided buffer and to not be optimized away."

On another note, searching for memset_s and openbsd yielded this hit from 2012:

[https://mail-index.netbsd.org/tech- security/2012/07/22/msg00...](https://mail-index.netbsd.org/tech- security/2012/07/22/msg000540.html)

Which seems to point back to:

[https://mail-index.netbsd.org/tech- userlevel/2012/02/25/msg0...](https://mail-index.netbsd.org/tech- userlevel/2012/02/25/msg006157.html)

So I guess the "trick" outlined in the (very lucid) post has been known for a while.

<comment><USER33> Thanks. I had missed the part in the article about the C11 changes.

</comment></comment></comment></comment></comment></comment><comment><USER44> Does anyone have any advice on articles about C compiler optimizations in general (especially gcc)? I'm doing my first serious C work in ten years, and I keep wondering if I should fuss with things like this or let the compiler handle it all:

        foo->bar->baz[i].oof = foo->bar->baz[i].durb + meep;

vs

       what *tmp = foo->bar->baz[i];
       tmp->oof = tmp->durb + meep;

EDIT: I'm not asking for a link to this:

[https://gcc.gnu.org/onlinedocs/gcc/Optimize- Options.html](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)

I'm asking if there is _advice_ about it. Any overviews with common pitfalls, advice on when to use -O1 vs -O2, specific optimizations to turn on/off, etc.

<comment><USER4>
        foo->bar->baz[i].oof = foo->bar->baz[i].durb + meep;

This is fine, no need to "optimize" anything. This kind of common subexpression elimination should be done by any modern compiler (for any language!) and the algorithm behind it is taught in university classes too.

Most of the time it's safe to use -O3. If you're doing numerical code with floating points -ffast-math is also pretty safe if your code is correct (ie. no NaN/Inf bugs). Almost the only reason to turn off optimization (-O0) is when higher optimizations make using a debugger harder.

Here's a pretty nice article with some specific optimizations that GCC can (or can't) do. It's pretty old, though, the examples were done with GCC 4.2.1, current version is around 4.9.

[http://ridiculousfish.com/blog/posts/will-it- optimize.html](http://ridiculousfish.com/blog/posts/will-it-optimize.html)

These days Clang can be as good or better than GCC most of the time. The exceptions are in more exotic code like kernel space stuff or micro controller programming.

There's no room for guesswork if you actually want to optimize code, so spend some time reading the assembler output from your compiler as well as benchmarking the results. I usually use objdump -d objfile.o to look at assembly output.

<comment><USER44> Really appreciate everyone's replies! A related question about my example: what if I want to assign the pointer dereference to `tmp` to improve readability (rather than avoid multiple traversals). Is there any reason _not_ to use a tmp variable (presumably with a better name)?

<comment><USER45> >what if I want to assign the pointer dereference to `tmp` to improve readability

I personally find code like that harder to follow. The first version is clearer than the second (and you forgot to take the address of foo->bar->baz[i]).

<comment><USER44> > and you forgot to take the address of foo->bar->baz[i]

Ha, I was afraid of that. :-) Still re-learning when I need that with arrays and when not.

</comment></comment></comment></comment></comment><comment><USER46> Why would the compiler be allowed optimize away a call to a perfectly valid function? This seems like it's allowing to compiler to make judgement calls on whether or not your code is worthy of being executed.

<comment><USER47> It's because memset is a standard function and has a defined standard way of acting, with the most important part being that it doesn't produce any side- effects. It's also worth noting that accessing memory that's no longer in the current scope is undefined-behavior, so the compiler can assume it doesn't happen. Thus the memset has absolutely zero effect on the actual program and isn't necessary.

In _general_ this isn't a big deal. It's only a big deal here because we're working on the assumption that you might have an issue in your code that invokes undefined-behavior and access contents of memory that you're not supposed to be looking at anymore, and the compiler's just assuming that your program won't ever allow that.

<comment><USER48> What if one made some trivial use of the block of memory after having performed the memset, say something like this:

       void
       dosomethingsensitive(void)
       {
            uint8_t key[32];
            ...
            /* Zero sensitive information. */
            memset((volatile void *)key, 0, sizeof(key));
            key[0] = key[1] + 1;
       }

Would that thwart the optimizer, or would it also see through that usage and eliminate it as well?

<comment><USER47> You should keep in mind that the memset call is almost guarenteed to be inlined. So your code actually looks like this:

        void
        dosomethingsensitive(void)
        {
            uint8_t key[32];
            /* ... */
            int i;
            for (i = 0; i < 32; i++)
                key[i] = 0;
            key[0] = key[1] + 1;
        }

Assuming the optimizer is sufficiently smart, then it'll remove that 'for' and it'll remove the addition after it in the same fashion.

</comment></comment></comment></comment><comment><USER49> Does GCC include any flags to prevent this sort of detrimental optimization?

<comment><USER50> There's a bunch listed ([https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Optimize- Options....](https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Optimize- Options.html)), including

-O0 // Do Not Optimise

This sounds like it should do the trick (but I've not done C coding for quite some time, so I don't know if there's a nuance as to why it wouldn't), but would also presumably kill any other optimisation.

A better option may be to combine that with pragmas ([https://gcc.gnu.org/onlinedocs/gcc/Function-Specific- Option-...](https://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option- Pragmas.html)) to switch optimisation levels within the code.

Anyone who's played with GCC recently know whether this would work or not?

</comment></comment><comment><USER51> > on C11 […] you can use the memset_s function

How is the case for modern C++? Are there `vector` or smart pointer alternatives that reliably zero the memory in the destructor?

</comment><comment><USER41> It seems like ideally what we need is a language designed for as-fast-as- secure computation, JIT for the specific architecture it is going to run on to ensure no differences in timing, energy use, or anything (within whatever bounds are achievable) even in the face of different cache layouts, CPU optimizations and similar and which makes it a point to clean up everything that is not meant to be returned.

</comment><comment><USER52> If your goal is just to "burn" the memory, why not write your own loop that copies some arbitrary piece of data that the compiler can't optimize out over the memory's contents? Do something like fill the buffer with its own pointer address.

<comment><USER28> It's been stated here already. You can write whatever you want into it. It doesn't matter. What matters is that the compiler realizes there's a dead store going into it, i.e. that the data is thrown away after it's written. So it can optimize out any write, since no conforming program can read that data after it's thrown away.

</comment></comment><comment><USER53> A sufficiently malicious compiler could keep around a copy of the key in non- volatile memory.

</comment><comment><USER54> The article the completely obvious:

        /* implemented in another translation unit */
        void zero_for_sure(void *data, size_t size);

        void func(void)
        {
          char securedata[42];
          /* ... */
          zero_for_sure(securedata, sizeof securedata);
        }

The key here is that our zero_for_sure is an external function in a separately translated file. In the absence of a stunningly advanced global optimization that peeks into other previously compiled units, the compiler has no idea what zero_for_sure does, and so it has to earnestly pass it the given piece of memory.

In turn, zero_for_sure is just this:

       void zero_for_sure(void *ptr, size_t size)
       {
          memset(ptr, 0, size);
       }

The compiler has no idea where ptr might come from since this is an external function, and so it cannot optimize away the memset.

Only if the compiler could consider the whole program together could it still optimize this.

In fact, you don't even need this function, just a dummy external function:

       void zero_for_sure(void *ptr, size_t size)
       {
          char securedata[42];
          /* ... */
          memset(securedata, 0, sizeof securedata);
          commit(securedata);
       }

Of course, commit is a noop which just returns. But the compiler doesn't know that because commit is in another translation unit.

The only optimization card that the compiler could pull here is since securedata is going away (so that it is illegal for commit to stash a pointer to it), it's okay to call commit with a pointer to some _other_ block which contains zeros, and not actually securedata.

With any trick like this, you should inspect the object code to make sure it's doing what you think it's doing.

Oh, and sizeof doesn't require parentheses when the operand is an expression; they are required when a type name is used as an operand.

<comment><USER41> From the article, _" Some people will try this with secure_memzero in a separate C file. This will trick yet more compilers, but no guarantees — with link-time optimization the compiler may still discover your treachery."_

[https://gcc.gnu.org/wiki/LinkTimeOptimization](https://gcc.gnu.org/wiki/LinkTimeOptimization)

[http://llvm.org/docs/LinkTimeOptimization.html](http://llvm.org/docs/LinkTimeOptimization.html)

<comment><USER55> Move the func into a dynamically linked library.

Thanks to the performance requirements of dynamic linking it's going to be a really long time until we have dynamic linker peeking into .so files and checking what a func does.

<comment><USER41> That certainly does it, yes. Though that's more complicated than the solution offered here, and of course now the right thing to do is just a memset_s.

</comment></comment></comment></comment><comment><USER56> You can have a function that wrapps memset with zero argument this wrapper should be in a different shared library, this way the compiler will not follow it; wait, that's exactly what memset_s is,

<comment><USER41> Not exactly. There's no reason memset_s can't be understood by the compiler, inlined, and optimized, so long as those bits still get zeroed. That's not the case for any of the other approaches.

<comment><USER56> the compiler should not make any assumption about what memset_s is doing (same goes for user defined memset wrapper function in different shared library - the implementation of that function is not known at compile or link time); if it can't make such assumption then it can't optimize the call out.

<comment><USER41> I think you misunderstand me. There is no guarantee that there will be no optimization _of_ or _around_ memset_s (at least, not provided by the standard), and we don't want one. What the standard has done is assured us that it will not be optimized _away_ \- that the effect of zeroing that memory will be treated as visible even if the memory is otherwise dead. Allowing the compiler to optimize without changing semantics is _desirable_ , and is permitted by the standard but prevented by the attempts to erect artificial walls through linking (and also by the volatile function pointer in the article), so memset_s - in addition to being clearer - is a technically superior solution.

</comment></comment></comment></comment><comment><USER57> I had no idea that such things are possible in C. The things about I've read recently (the "friendly" C suggestion) and this seem like violations of the spirit of the language. And for what, really? The language looses its signature predictability, which to me seemed like a great feature of C.

If you write crappy code and expect the compiler to fix it for you, you should maybe consider another language. I can only imagine how hard it is to write reliable system software in a language that does these things.

<comment><USER58> > _If you write crappy code and expect the compiler to fix it for you, you > should maybe consider another language._

This seems rather to be a case of writing good code and having the compiler break it for you.

<comment><USER57> Yes it is. You misunderstood my point, which was about the purpose of existence for such optimizations - they are meant to improve code, which presumably needs improvement. But if your code needs improvement, then why not go for a higher level language?

BTW, I gave you an upvote by accident :D

<comment><USER28> They are meant to make the code run faster. If your code needs optimization, going for higher level languages is seldom a good idea.

You could try do low level optimizations in your C or assembly, but for most programs this will eventually backfire. So letting the compiler do its job is actually a good thing.

</comment></comment></comment></comment><comment><USER59> Couldn't you just compile these functions with optimization turned off, in a separate binary or something?

<comment><USER60> You would also need to link with optimizations turned off (or link dynamically, making the behavior undetermined at link time) to be sure. Linker optimizations have been a thing for a few years now.

</comment></comment><comment><USER61> Wouldn't returning the passed memory block through the return fix the optimization issue?

</comment><comment><USER62> For those of you unaware, Colin Percival (author of the blog) was for many years the FreeBSD Security Officer and he's highly recognized in the field for his expertise.

He also runs [http://www.tarsnap.com/](http://www.tarsnap.com/) which is arguably the most secure (and cost effective) back up solution in the market.

(I'm in no way affiliated with Colin and/or Tarsnap. Just a fan of his work and humble attitude.)

<comment><AUTHOR> _humble attitude_

I'm guessing you haven't seen the "comeback of all time" thread...

<comment><USER62> I haven't.

But I think it's super funny and cool that you (yourself) are pointing it out.

All the best with you.

Edit: just read the "comeback of all time". That was really funny. Nice nod from PG as well. For those of you unaware like me: [https://news.ycombinator.com/item?id=35083](https://news.ycombinator.com/item?id=35083) Colin is our resident mathematical genius :)

<comment><USER63> Thanks for linking that. It's always interesting to see posts from several years ago and reflect on how things turned out (if you go up a few parents you can see discussion about tarsnap and dropbox makes a brief appearance).

</comment></comment></comment></comment><comment><USER64> When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03:

        #include <string.h>

        void doSecure(void)
        {
            /*char key[32];*/
            char *key = (char*) malloc(sizeof(char)*32);

            memset(key,sizeof(char),32);
        }

        int main(void)
        {
            doSecure();

            return 0;
        }

        -- key on stack

        main:
        .LFB13:
            .cfi_startproc
            xorl	%eax, %eax
            ret
            .cfi_endproc

        -- key on heap

        main:
        .LFB13:
            .cfi_startproc
            subq	$8, %rsp
            .cfi_def_cfa_offset 16
            movl	$32, %edi
            call	malloc
            movabsq	$72340172838076673, %rdx
            movq	%rdx, (%rax)
            movq	%rdx, 8(%rax)
            movq	%rdx, 16(%rax)
            movq	%rdx, 24(%rax)
            xorl	%eax, %eax
            addq	$8, %rsp
            .cfi_def_cfa_offset 8
            ret
            .cfi_endproc

<comment><USER12> A more realistic idiom is memset followed by free. The free provides a solid hint to the compiler that the object is dead without relying on escape analysis.

<comment><USER64> Naturally, however adding free made no difference in this case. I guess if your dealing with a raw pointer rather than an array type, gcc cant be sure what memory you intend to erase.

</comment></comment></comment><comment><USER65> This sort of thing would be exactly what should go into the "Friendly C" dialect being chatted about the other day--for things like zeroing memory, it's very unexpected that a compiler would be like "nah, not feeling it...nobody will notice anyways".

<comment><AUTHOR> If you're not worried about writing in a language which is widely supported, just use memset_s and tell people to find a C11 compiler.

<comment><USER66> Or have your build system add memset_s.c to their compile on systems that don't have it.

<comment><USER12> A C11-unaware compiler will not be guaranteed to provide the always zero semantics, any more than your own secure_memzero could be optimized away.

</comment></comment></comment></comment><comment><USER18> Just put it in a shared library and don't worry about it. Why all these compiler-specific brittle solutions when simply putting a function in a .so will ensure it's being called and will prevent any link-time optimisations.

<comment><USER67> Last time I checked, there was nothing specifically preventing an implementation of C from doing whole-program optimization at runtime, even to the point of dynamic library calls.

So: this is not something you can rely on always working. Yes, it works currently, but it is not guaranteed to always do so.

</comment></comment><comment><USER68> Well, if the buffer is so critical and yet small, why not just free it and re- allocate the whole thing next time we use it.

<comment><USER69> Because freeing memory doesn't erase its contents.</comment></comment>


When is it ok not to open all source code? - <AUTHOR> https://gds.blog.gov.uk/2014/10/08/when-is-it-ok-not-to-open-all-source-code/

<comment><USER2> #1: Keeping certain configuration details a secret (e.g. passwords, which ports are open, versions of software, etc). Good idea. Best practices even.

#2: Hide the code/software that performs security-enforcing functions. Um... What? No. This is stupid. This is exactly the kind of thing you _want_ out in the open so people can find flaws and let you know about them before "the bad guys" get ahead of you. It's Wizard of Oz security: Pay no attention to the software behind the curtain.

#3: Who cares? Why do they feel the need to justify delaying the release of code? Of course you'll want time to prepare it "for public consumption." As long as it gets opened up in a timely matter.

<comment><USER3> #3 appears to be a catch-all for "we haven't decided our policy is yet, and publishing the source code early, while we're still considering the options, forces us to make a premature public statement."

For example, suppose the government was going to establish a new video codec for its own video releases (ie, suppose that Dirac doesn't exist). There are several options: create a new and unencumbered license, negotiate a license for an existing system, or purchase the patent right from the patent holder.

The final choice depends on the cost to develop a new codec, the success of that codec, and the cost of buying or licensing the patent(s). The government can explore all of these at the same time, eg, set up a group to develop a new codec while negotiating with various rights-holders.

The new codec might be finished while the negotiating is ongoing. The government knows how well it fits their goals, but the rights-holders do not. This gives a negotiation advantage to the government.

On the other hand, if the completed codec were immediately published, that advantage disappears. The rights-holders might decide to raise their prices after seeing just how bad the new codec is, which makes the government goal of more open access to their video archives more expensive.

Thus, the government could rightly "judge the public interest not to be served by publishing [their] own software", even if, after the negotiations have completed, the software will be published.

</comment></comment><comment><USER4> 1\. Security by obscurity

2\. Security by obscurity

<comment><USER5> Also, the distinction is largely pointless - vulnerabilities are not limited to some magic "security enforcing functions", so if the argument had any value, you'd have to keep all of the code secret. The security of a system tends to depend on all of the code that is in some way reachable from the outside.

Also, they list antivirus software as a security measure - all the more reason to publish it all so people with some actual expertise in IT security can have a look at it.

<comment><USER2> Not only that but the expectation that you can keep your AV vendor a secret is ridiculous. Especially with tens of thousands of employees having a system tray icon in direct view and hundreds to thousands of techs expected to be able to install/re-install said software.

Not to mention the fact that big contracts with AV/security vendors are usually public knowledge and easily accessible. Heck, they probably have press releases indexed by Duck Duck Go!

</comment></comment></comment><comment><USER6> I'm curious if someone more knowledgeable than me in the security world could elaborate on where most people tend to sit on this spectrum of openness. I figure "obscurity" reduces the number of potential attackers that have the capability of cleverly attaining the information being kept obscure, but at the cost of not having much of the public available to evaluate the software's integrity.

My uninformed guess is many people stick to the former.

<comment><USER2> Finding vulnerabilities in closed source software is just as easy as finding vulnerabilities in open source software. The key differences are:

* Transparency.

* The ability to fix it yourself.

Also consider this: No one submits patches to fix vulnerabilities in closed source software because that's not possible without the source. This results in all sorts of problems that just don't exist when the code is available:

* After reporting a vulnerability you now have to wait for the vendor to fix it. If the vulnerability isn't out in the open (yet) they might take their sweet time while you nervously twiddle your thumbs.

* If the vendor doesn't support the product anymore (or the vendor doesn't exist anymore) then there's really no options at all. You have to live with the vulnerability or get a new product.

* When the vendor releases a fix how do you know if they fixed the core vulnerability or just the edge case that was given to them? All too often vendors apply hacks to detect specific edge cases instead of fixing underlying problems. This is why attackers are able to take advantage of _old_ vulnerabilities by means of simple fuzzing (or just being clever).

For example, I reported a horrific information disclosure vulnerability (SSNs in the clear) once and their 'fix' was to base64-encode the data. If I didn't keep track and follow up with them (took them four months to release that 'fix') it is likely that vulnerability would still be present.

There's actually a lot of other problems related to closed source vulnerabilities and fixes but I'm out of time...

<comment><USER6> I appreciate the time you did spend writing this comment. I don't work in the security world so it is nice to know some arguments for open-source software as a way of removing vulnerability in software.

</comment></comment></comment><comment><USER7> Also: [https://identityassurance.blog.gov.uk/2014/10/09/how-we- use-...](https://identityassurance.blog.gov.uk/2014/10/09/how-we-use-open- source-code-on-the-identity-assurance-programme/)

Left a comment there but it's awaiting moderation. The GDS do a good job for the most part, but I very strongly disagree with how they're handling this one.</comment>


Reflections by a Dallas police officer - <AUTHOR> http://www.hlswatch.com/2016/07/09/reflections-by-a-dallas-police-officer/ <comment><USER2> > These men who died were men of guardian hearts protecting citizens' > constitutional rights as warriors in a battle for their lives. And that > dichotomy is a sense of struggle for me as an advocate for stronger police > community relations, an inclusive in-group identity for citizen and police > where they are not pitted against one another. It is imperative that we > continue to deal with and overcome inherent bias and its effects on human > beings.</comment>