• 0 Posts
  • 112 Comments
Joined 2 years ago
cake
Cake day: June 10th, 2024

help-circle
  • Telegram can serve you your old “Cloud” messages, in a decrypted form, on a new device, without any communication with the old device.

    This means that they possess the keys to decrypt the messages, since they can send them to you in a decrypted form.

    Those messages can’t even be encrypted with your cloud password (which would be a pretty weak encryption anyways), because you can reset the cloud password via your recovery email, and still retain access to your messages.

    Contrast this with encrypted chats on Matrix, where you have to go through the device verification procedure, which prompts the old device to send decryption keys to the new device (it’s actually more complicated but this gets the point across). If you lose access to all your devices (and your recovery key), your encrypted messages are gone, the server admin can’t restore them because they simply don’t have the key.

    No one can’t prove that Telegram use MTProto to encrypt content sent using Cloud Chat, stores them encrypted, and them decrypt them upon opening because the source code for MTProto is closed. So how can you prove that what you’re saying is the way they use?

    This is a distinction without a difference.

    My claim is:

    They possess the keys to decrypt your messages

    Whether this is implemented via MTProto encryption or disk encryption or whatever, it doesn’t matter, they can read your messages if they want to.

    Telegram is actually pretty transparent that Cloud chats are not e2e encrypted in their FAQ. They also go on to babble about “MTProto client-server encryption” but if you spend 2 minutes looking at it, you can see it’s just 256-bit AES with a shared key generated via Diffie-Hellman, not too dissimilar from plain HTTPS. In that sense it’s about as secure as e-mail over encrypted IMAP/SMTP, or IRC over TLS, or DMs here on lemmy.

    They also claim that their at-rest encryption keys are separate from the data they encrypt, and claim that somehow this “requires court orders from multiple jurisdictions” to force them to give over your data, which is just ridiculous from a legal standpoint and won’t stand up in court. And actually, it’s way more likely that they will just cave in and give up your message history without a lawsuit at all, just look at what happened to Durov in France.


  • All data sent to Telegram’s servers will be encrypted once they reach the servers

    Except for “secret chat” (which are only 1-on-1 chats, have flaky client support, and require both participants to be online at the same time to initiate; in other words, they are near useless) - this is just simple at-rest storage encryption. They possess the keys to decrypt your messages (again, except for secret chats), because that is necessarily what happens when they serve those messages to recepients.






  • I think if you have some use-case that Wayland doesn’t fulfill, it’s totally fine to just pin some version of Plasma and stick with it. Maybe even switch to Trinity. Chances are it will keep working for like a decade or more.

    I still use kdenlive 18.08, because I know how to use that version, and it does what I need it to do perfectly well. They broke something I needed in 19.whatever (I don’t remember what it was anymore), so I just pinned it and kept using it ever since. Maybe one day I’ll try to figure out the latest version, but there’s no real incentive for me to do so.


  • For context, I’m using NixOS, not Arch, but it’s a similar enough idea. I have a tiling/tabbed WM configured just the way I like it, and a window switcher thingy, and it makes juggling hundreds of windows really easy and quick. Combined with a terminal-based editor, a custom setup for my shell, and direnv for easy environment switching, I can be switching between a dozen different projects within a single day (sadly a requirement for my work right now).

    Whenever I look at how my colleagues with KDE/Gnome are managing their workflows, it makes me appreciate the work I put into my setup a lot.

    Also, I have a whole bunch of shell aliases and scripts for tasks I do often.

    Sure, you can configure any distro to do that, but things like Ubuntu or Fedora would get in the way. At some point, when you want to choose (or even write) every component of the system and configure it yourself, it’s easier to just build from scratch rather than start with a lot of pre-configured software and remove parts.



  • Is it shown that there are significant performance benefits to installing daemons and utilities à la carte?

    No, not really.

    Is it because arch users are enthusiasts that enjoy trying to optimize their system?

    This is IMHO the most important aspect. The thing they’re trying to optimize isn’t performance, though, it’s more “usability”, i.e. making the system work for you. When you get down to it and understand all the components of the OS, and all the moving parts within, you can set it up however you prefer and then combine them in novel ways to solve your tasks more quickly.


  • balsoft@lemmy.mltoScience Memes@mander.xyzAeroplane
    link
    fedilink
    English
    arrow-up
    5
    ·
    2 months ago

    if the autopilot is engaged, you can’t physically move the wheels, because it is moving them for you.

    I’m pretty sure on newer 737s the autopilot disconnects when it detects a sufficient physical force on the yoke. But yeah the button is easier and safer.

    most important: the switch for the “fasten seatbelt” sign is usually on the bottom of the top panel. You can flip it on and off as much as you want. (Older planes will also let you do this with the “no smoking” sign).

    Gee, how the hell did everyone miss this? The most important control element.


  • balsoft@lemmy.mltoScience Memes@mander.xyzAeroplane
    link
    fedilink
    English
    arrow-up
    8
    ·
    2 months ago

    Chill, it’s just a shitpost.

    BTW, a regular person can likely fly and land a 737 with some basic ATC instructions, there have been multiple experiments demonstrating this (in a simulator). A guide like this would be immensely helpful in that situation.


  • balsoft@lemmy.mltoScience Memes@mander.xyzAeroplane
    link
    fedilink
    English
    arrow-up
    51
    ·
    2 months ago

    Few additions:

    • “reverse thrust” → “slow down (after you land)”
    • (at foot pedals) “Push both to brake (after you land), push one or the other to turn”
    • “go fast” → “go fast (keep levers together)”
    • “keep it above the ground” → “keep it above the ground, but not too high”
    • (at IAS indiciator) “how fast you’re going”, “keep between 170 and 400, lower to 140 when landing”
    • “make wings bigger” → “make wings bigger, required when taking off or landing”

  • I’ve heard about Linux being highly customizable and decentralized OS, and suddenly I can’t define my own shortcuts because there is a list of un-features?

    You can customize it to do whatever you want. Heck, you can write your own terminal emulator that does exactly what you need. But some things can be harder to do than others and require skills and experience. Once someone implements those harder things, they become a “feature”. Before then, therefore, they are an “un-feature”. See https://xkcd.com/1349/

    E.g. it is probably possible to set up your shell to use shift-selection for the command you’re currently editing, but shift-selection for the output of a previous command will require terminal support. You will have to make sure that the two don’t interfere with each other, which can be quite complicated.

    I already have my workflow and I’m trying to transfer it to Linux

    Linux is a different OS that, by default, does things differently from others. You can configure it to emulate some other UX, but it won’t necessarily be easy. In the meantime, you can install the micro editor, set EDITOR=micro, and then Ctrl+x Ctrl+e in bash to edit the command in a more familiar setting.


  • I think this is one of many un-features in Linux world where

    • It would benefit a beginner
    • It sounds simple but actually quite complicated to get right (especially if you aim to keep compatibility with things)
    • Anyone possessing the skills to implement it neither needs it nor cares about it

    As such, for you individually, I suggest just getting more comfortable with tmux (or zellij) and vi-like keybinds for text manipulation. Once you learn those (and set your readline mode to vi), you won’t look back. Oh, also, try Ctrl+x Ctrl+e in bash, it might help.

    Or switch to emacs and using it as a terminal emulator. In that case you will have to learn and use emacs keybindings, but the selection semantics in the “terminal” will be the same as in the “editor”.




  • I decided to write it myself for fun. I decided that “From Scratch” means:

    • No parser libraries (parsec/happy/etc)
    • No using read from Prelude
    • No hacky meta-parsing

    Here is what I came up with (using my favourite parsing method: parser combinators):

    import Control.Monad ((>=>), replicateM)
    import Control.Applicative (Alternative (..), asum, optional)
    import Data.Maybe (fromMaybe)
    import Data.Functor (($>))
    import Data.List (singleton)
    import Data.Map (Map, fromList)
    import Data.Bifunctor (first, second)
    import Data.Char (toLower, chr)
    
    newtype Parser i o = Parser { parse :: i -> Maybe (i, o) } deriving (Functor)
    
    instance Applicative (Parser i) where
      pure a = Parser $ \i -> Just (i, a)
      a <*> b = Parser $ parse a >=> \(i, f) -> second f <$> parse b i
    instance Alternative (Parser i) where
      empty = Parser $ const Nothing
      a <|> b = Parser $ \i -> parse a i <|> parse b i
    instance Monad (Parser i) where
      a >>= f = Parser $ parse a >=> \(i, b) -> parse (f b) i
    instance Semigroup o => Semigroup (Parser i o) where
      a <> b = (<>) <$> a <*> b
    instance Monoid o => Monoid (Parser i o) where
      mempty = pure mempty
    
    type SParser = Parser String
    
    charIf :: (a -> Bool) -> Parser [a] a
    charIf cond = Parser $ \i -> case i of
      (x:xs) | cond x -> Just (xs, x)
      _ -> Nothing
    
    char :: Eq a => a -> Parser [a] a
    char c = charIf (== c)
    
    one :: Parser i a -> Parser i [a]
    one = fmap singleton
    
    str :: Eq a => [a] -> Parser [a] [a]
    str = mapM char
    
    sepBy :: Parser i a -> Parser i b -> Parser i [a]
    sepBy a b = (one a <> many (b *> a)) <|> mempty
    
    data Decimal = Decimal { mantissa :: Integer, exponent :: Int } deriving Show
    
    data JSON = Object (Map String JSON) | Array [JSON] | Bool Bool | Number Decimal | String String | Null deriving Show
    
    whitespace :: SParser String
    whitespace = many $ asum $ map char [' ', '\t', '\r', '\n']
    
    digit :: Int -> SParser Int
    digit base = asum $ take base [asum [char c, char (toLower c)] $> n | (c, n) <- zip (['0'..'9'] <> ['A'..'Z']) [0..]]
    
    collectDigits :: Int -> [Int] -> Integer
    collectDigits base = foldl (\acc x -> acc * fromIntegral base + fromIntegral x) 0
    
    unsignedInteger :: SParser Integer
    unsignedInteger = collectDigits 10 <$> some (digit 10)
    
    integer :: SParser Integer
    integer = asum [char '-' $> (-1), char '+' $> 1, str "" $> 1] >>= \sign -> (sign *) <$> unsignedInteger
    
    -- This is the ceil of the log10 and also very inefficient
    log10 :: Integer -> Int
    log10 n
      | n < 1 = 0
      | otherwise = 1 + log10 (n `div` 10)
    
    jsonNumber :: SParser Decimal
    jsonNumber = do
      whole <- integer
      fraction <- fromMaybe 0 <$> optional (str "." *> unsignedInteger)
      e <- fromIntegral . fromMaybe 0 <$> optional ((str "E" <|> str "e") *> integer)
      pure $ Decimal (whole * 10^log10 fraction + signum whole * fraction) (e - log10 fraction)
    
    escapeChar :: SParser Char
    escapeChar = char '\\'
      *> asum [
        str "'" $> '\'',
        str "\"" $> '"',
        str "\\" $> '\\',
        str "n" $> '\n',
        str "r" $> '\r',
        str "t" $> '\t',
        str "b" $> '\b',
        str "f" $> '\f',
        str "u" *> (chr . fromIntegral . collectDigits 16 <$> replicateM 4 (digit 16))
      ]
    
    jsonString :: SParser String
    jsonString =
      char '"'
      *> many (asum [charIf (\c -> c /= '"' && c /= '\\'), escapeChar])
      <* char '"'
    
    jsonObjectPair :: SParser (String, JSON)
    jsonObjectPair = (,) <$> (whitespace *> jsonString <* whitespace <* char ':') <*> json
    
    json :: SParser JSON
    json =
      whitespace *>
        asum [
          Object <$> fromList <$> (char '{' *> jsonObjectPair `sepBy` char ',' <* char '}'),
          Array <$> (char '[' *> json `sepBy` char ',' <* char ']'),
          Bool <$> asum [str "true" $> True, str "false" $> False],
          Number <$> jsonNumber,
          String <$> jsonString,
          Null <$ str "null"
        ]
        <* whitespace
    
    main :: IO ()
    main = interact $ show . parse json
    
    

    This parses numbers as my own weird Decimal type, in order to preserve all information (converting to Double is lossy). I didn’t bother implementing any methods on the Decimal, because there are other libraries that do that and we’re just writing a parser.

    It’s also slow as hell but hey, that’s naive implementations for you!

    It ended up being 113 lines. I think I could reduce it a bit more if I was willing to sacrifice readability and/or just inline things instead of implementing stdlib typeclasses.