Varias cosas II

Hola, hace un tiempo que no actualizo mi blog, no obstante han pasado varias cosas desde la ultima vez que escribí.

Nuevas funcionalidades

Añadí una precaria funcionalidad de reply a los comentarios, que aunque el blog no tenga muchos, sin duda el software ha tomado un rumbo a un CMS algo más genérico y me pareció necesario. Por ahora solo permite 1 nivel de anidado, ya que estoy pensando en la mejor forma de limitarlo (n-niveles rompería el layout) y debido a las características del sistema de templates de Go no encontré una buena forma de hacerlo que no involucre JS.

También hay una funcionalidad para añadir páginas estáticas, lo cual lo hace un poco más versátil.


Fuera de esto estoy pensando en mover el desarrollo del blog a un repositorio aparte, ponerle un nombre (¿ideas?) y difundirlo un poco más, quizás encuentre gente que le sirva y quiera colaborar con un mini CMS hecho en Go.


Durante el fin de semana he estado estudiando un poco de Docker, un poco motivado por la meetup de DevOps Litoral y la charla de Germán y Manuel. La verdad avance mucho menos de lo que quería pero leí bastante sobre containers y demás.

The Force Awakens

El otro fin de semana me di el gusto de ver la nueva peli de Star Wars, sinceramente iba preparado para una decepción pero no fue así, me gustó mucho. No voy a contar muchos detalles fuera de eso :).

Blog update

I’ve added some features to this little piece of software. Mainly you will notice you can now get a proper RSS feed for the blog posts, for this I created a little small Go library which just uses the encoding/xml package of go STL. Also now it’s possible to access posts by pretty urls rather than by id, which is something I had to do a long time ago but forgot to do it far too many times.

I’m also working on a prettier admin interface based on SB admin bootstrap template.

A bunch of stuff

I’ve been quite busy but I’m still trying to learn a thing or two daily.


Termbox-go is a go wrapper to work with the Termbox library which allows to make simple console-based applications. It’s quite neat and easy/straightforward to do. I’ve been learning a thing or two with it. And it has been fun thing to do during the weekend, I also used it as a joke for a couple of friends parodying the “hacking time” segment of the movie Kung Fury, you can see it in this gist

example 1433166472_2015-06-01-103331_374x453_scrot.png

You could probably make things way more useful than this, but doing useless stuff is sometimes both fun and educative.


I’ve started building a small ruby app to scratch an itch in my company. Mainly management of client feedback and such. I’m using Sinatra+Datamapper because I want to finish it quickly, later on I might port it to Go if I have the time, but Ruby is good enough for now. This has taught me how to better organize a Sinatra project (since I don’t want to cram all that functionality on a single module) and testing the framework actions.


Cryptography course keeps being amazing, but I’m a little delayed with the course (which was to be expected). I’m not too confident to have enough time to take the final exam, but in the worst case scenario I might just take the second term course to reinforce my knowledge (and implementing all other crypto methods that are not part of the course homework). The last week homework consisted on integrity validation, which is a little less exciting than other algorithms but it was fun enough for me to do the assignment. But basically it involves generating a SHA256 sum of a file backwards progressively in blocks of 1024 bytes, I made use of the io.ReaderAt interface for this.

package sha256

import (


func HashBlock(block []byte) []byte {

    hash := sha256.New()
    return hash.Sum(nil)

func HashFile(input io.ReaderAt, size int64) []byte {
    var current []byte = make([]byte, 1024)
    var previous []byte

    rest := size % 1024

    var last []byte = make([]byte, rest)
    _, err := input.ReadAt(last, size - rest)
    if err != nil {
    var offset int64 
    if rest != 0 {
        offset = size - rest - 1024 
        previous = make([]byte, 32)
        copy(previous, HashBlock(last))
    } else {
        offset = size - 1024    

    for  offset >= 0 {
        _, err := input.ReadAt(current, offset)
        if err != nil {

        copy(previous, HashBlock(append(current, previous...)))

        offset -= 1024

    return previous


I’m a little bummed that there wasn’t any meetups of coding groups nearby, I find them extremely motivating to keep learning, perhaps I should make some sort of compendium of what I’ve learned these months and present it as a lightning talk, that might make it more interesting. But I can’t really decide which topic I like the most to talk about. Tough choices.


This is a fun one, I’ve been introduced to SWOT Analysis by an episode of Silicon Valley by the infamous character Jared. I thaught it was silly at first but I gave a try to the method in a couple of situations and it comes in handy when having to take hard decisions. It’s funny how sometimes some completely unrelated tool heard by pure coincidence can prove itself useful at times. It seems to be meant to work on single “yes or no” kind of situations, I wonder if there are similar tools to help making decisions on several alternatives.

example 1433166684_SWOT.jpg SWOT in action (keep in mind that showing your SWOT session to any of the parties involved might end up in really awkward or life-threatening situations)

Blog Actualizado (Markdown y uploads multimedia)

Le agregue al blog la capacidad de escribir con markdown (ya que el editor wysiwyg era horrendo) así como la capacidad de subir imagenes, archivos y videos, los comentarios también soportan markdown pero no ciertos elementos html por cuestiones de seguridad. Los posts ahora tienen 2 tipos de formato para conservar compatibilidad con los posts más antiguos, aunque el editor html esta deshabilitado en el admin.

Archivos multimedia

example 1431808837_go.png


Often people, especially computer engineers, focus on the machines. They think, “By doing this, the machine will run fast. By doing this, the machine will run more effectively. By doing this, the machine will something something something.” They are focusing on machines. But in fact we need to focus on humans, on how humans care about doing programming or operating the application of the machines. We are the masters. They are the slaves. - Yukihiro Matsumoto

  • Esto
  • Es
  • Genial

Decent Code Blocks at last!

class OneTimePadEncoder
  def self.encode(message,key)
   # (hex_message = message.unpack("H*").pop.hex ^ hex_key = key.unpack("H*").pop.hex ).to_s(16)

  def self.decode(ct,key)
  def self.xorpair(a,b)
    a = a.unpack("C*")
    b = b.unpack("C*")    
    result = [] { |x| result.push x[0] ^ x[1] unless x[1] == nil }

como siempre pueden obtener el código en github

Block Ciphers

Disclaimer: These posts help mostly myself to assimilate what I’m learning about cryptography and should not be taken as a final word or academic truth. I encourage you to correct me if you find that I’m wrong.

So as I promised here is my entry on what I’ve learned lately about Block Ciphers and their mode of operation. Basically a Block ciphers allows us to encrypt a block of n bits of data data, there are many block cipher implementations, among the most popular ones are DES ( now deprecated) 3DES, AES.

AES particularly operates on blocks of 16 bytes ( 128 bits) with keys ranging from 128 to 256 bits. Therefore we need additional constructs to actually make the block cipher useful for larger pieces of data, there are several modes of operation of block ciphers and among the most popular ones there are CBC (Cipher Block Chained) and CTR or Counter mode. CBC basically works by creating a random Initialization Vector (IV) of 16 bytes and XORing it against a block of the same length on the plain text message, then it uses AES to Cypher the result with a chosen key. Subsequently we use the output of this output and XOR it against the next block of the plain text message. Best explained by this diagram: example 1431810452_601px-CBC_decryption.svg.png example 1431810440_Cbc_encryption.png

The IV is usually prepended to the message and it’s retrieved when needed for decryption which is basically the same process but using the AES decryption algorithm first and then XOR it against the IV. Then we feed the next iteration using the cipher text from the previous step.

example 1431810511_Ctr_encryption.png example 1431810516_Ctr_decryption.png

There is also another mode of operation which is Counter mode, which instead of relying on the output of the encryption algorithm to cipher the next chunk of plain text it just appends or adds a unit to the Initialization Vector and XORs it with the plain text. It’s worth mentioning that while on CBC we need to perform an AES decryption to retrieve the message, in CTR mode we will actually perform the encryption in both ways. What is interesting about CTR is that since we can easily calculate IV + 1 without needing any other additional processing we can make this process concurrent, and that’s what makes it an interesting algorithm to implement with go.


In order to implement the algorithm we will use some libraries, and we will build some functions of our own, first is the aes package in the golang library. Then a convenience XOR function defined as:

package tools

// XORS 2 []byte
func XOR(a, b []byte) []byte {
    var result []byte = make([]byte, len(a))
    for i := 0; i < len(a); i++ {
        result[i] = a[i] ^ b[i]
    return result

The function is pretty straightforward, it takes two bytes as parameters and performs a bitwise XOR on each one, it will fail if the arrays are of different sizes, but since we’re supposed to work with 16 bytes it shouldn’t matter.

We’d define the CTR struct with a factory method to set the key

package ctr

import (


type CTR struct {
    Cipher cipher.Block

func New(key []byte) CTR {
    cipher, err := aes.NewCipher(key)
    if err != nil {
    return CTR{cipher}

and some convenience methods to cipher each block with AES:

func (this CTR) EncryptBlock(ct []byte) []byte {
    var pt []byte = make([]byte, aes.BlockSize)
    this.Cipher.Encrypt(pt, ct)

    return pt

This one is just for having a better legibility

func GrabBlock(full []byte, blockSize int, index int) []byte {
    return full[index : index+blockSize]

Then we implement the Encrypt method as follows:

func (this CTR) Encrypt(pt []byte) []byte {
    var iv []byte = make([]byte, aes.BlockSize) 
    _, err := rand.Read(iv) // We generate a random IV of 16 bytes

    if err != nil {
    CT := append([]byte{},iv...) // we append the IV to the cipher text, 

    max := len(pt) / aes.BlockSize  // we determine the maximum blocks of 16 bytes we can get from the plain text
    rest := len(pt) % aes.BlockSize  // we determine the length of the remaining bytes to get from the plaintext
    CTChan := make(chan []byte, max +1)  // we define a channel to send our CT blocks, of size max +1 to store all the bytes
    IVChan := make(chan byte, max +1) // we define a channel to send our modified IV 
    for i := 0; i <= max; i++ {

        var blockSize int 

        if i == max {
            blockSize = rest
        } else {
            blockSize = aes.BlockSize

        block := GrabBlock(pt, blockSize, i * aes.BlockSize) // we grab a block from the plaintext

        go func( Block []byte) {

            CTChan <- tools.XOR(Block, this.EncryptBlock(iv)) //we cipher it against the iv and send it back to the CT channel
            IVChan <- iv[len(iv)-1] + 1 // we send the increased counter through the IV channel

        }( block )

        iv[len(iv)-1] = <- IVChan  // we receive and effectively increase the counter

    go func(){
        close(CTChan)  // we close the ct channel

    for val := range CTChan{
        CT = append(CT,val...) // we append the values from the channel to the final CT

    return bytes.TrimSuffix(CT, []byte{0}) // we remove any zeroed bytes at the end of the CT


The decryption method is pretty similar:

func (this CTR) Decrypt(ct []byte) []byte {
    var PT []byte
    iv := ct[:aes.BlockSize]  // we extract the IV from the beginning of the CT 

    CT := ct[aes.BlockSize:] // we slice the actual CT for convenience

    max := len(CT) / aes.BlockSize
    rest := len(CT) % aes.BlockSize
    PTChan := make(chan []byte, max +1)
    IVChan := make(chan byte, max +1)
// this code does pretty much the same

    for i := 0; i <= max; i++ {
        var blockSize int

        if i == max {
            blockSize = rest
        } else {
            blockSize = aes.BlockSize

        block := GrabBlock(CT, blockSize, i * aes.BlockSize) // now we grab blocks from the CT instead of PT
        go func( Block []byte) {

            PTChan <- tools.XOR(Block, this.EncryptBlock(iv))  // we ENCRYPT (not decrypt) the iv and send the XOR back
            IVChan <- iv[len(iv)-1] + 1

        }( block )
        iv[len(iv)-1] = <- IVChan

    go func(){

    for val := range PTChan{
        PT = append(PT,val...)

    return PT

And voilá, basically we have our CTR encryption system ready, you can find the full code and a partial CBC implementation on this github repo.

This was a very exciting thing to do and I learned a lot about cypto, golang channels and more. I hope you liked it!

Actualización de blog

Me tome unos minutos para mejorar un poco el código de este blog, principalmente separar los controladores de la funcionalidad del admin en un paquete aparte y en distintos controladores (ya que antes era un caos). De paso añadí un contador de comentarios.

Lo lindo de ir actualizando el blog de esta manera es que siempre puedo aprender un poquito más de Go en el proceso.

Pueden ver el código aquí.



New layout and backend

I remade the layout and backend of my blog, now it is made in the Beego framework,
I must admit that getting used to it it has been a bumpy road for me, mainly because it's a total new way of web programming for me.
As you can see most there are missing features from the previous blog, mainly comment support and photo uploading, but I plan to add
support for those in the coming months ( probably better implemented than on the previous blog anyways).

As always the code can be downloaded at Github, if you want to learn how to make a Beego website it might prove useful since it's a simple project
anyway be warned that this was made in a hurry in my spare time so it CAN and WILL be improved on the coming months, mainly separation of controllers
( the admin controller is a mess), added validation, loading  of configuration values and more.

Well, it's nice to have something new to play with. I hope you like it.

Introducing ShareMyFiles(Eos Sharer)

Let me introduce you our pet project here at EosWeb, it's codename is  sharemyfiles ( but probably it's going to be changed to a proper name somewhere in the future). The main idea is to have a personal file sharer that it's easy to use, requires no configuration and it's powerful. So far the development of sharemyfiles has been really interesting and rewarding, as a side project I've been able to have a more realistic approach at developing Go applications.

Right now it's mostly a prototype not really recommended for any serious usage, but we're gradually incorporating new features, such as Zip archive download last week, and probably we will make it way more secure on the coming months and add better usability.

That's cute, but show me the code

The code is hosted at github, you can feel free to download it, tinker, destroy, recompose, print the code and then use it as a fuel for your BBQ if you don't like it. But if you are interested in contributing, we will be happy to have your help.

Good Gophers Share

At EosWeb we are working on a new  desktop/mobile application. This is a new venture far away from our traditional web application solution, and we hope we succeed as coding in Go is both exciting and interesting. I don't want to give to much details, not by the sake of secrecy but more because it's really on early stages these are some of our most defined goals:

  • Ease to install and use
  • Multi platform support ( Linux/Android/OSX/Windows)
  • Multiple user interface: we seek to mantain both a GUI version and command line interface for servers.
  • Open Source

Keep tuned for details