{"id":34163321,"url":"https://github.com/unix4fun/ic","last_synced_at":"2026-03-13T04:31:12.993Z","repository":{"id":19661684,"uuid":"22914873","full_name":"unix4fun/ic","owner":"unix4fun","description":"IC4F / Irc Crypto 4 Fun, a simple IRC encryption mechanism.","archived":false,"fork":false,"pushed_at":"2020-11-22T08:21:43.000Z","size":414,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-12-18T04:15:45.731Z","etag":null,"topics":["crypto","go","golang","irc","irc-client","irc-encryption","plugin","python","weechat"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unix4fun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-13T12:33:17.000Z","updated_at":"2021-10-07T22:09:32.000Z","dependencies_parsed_at":"2022-08-24T14:07:25.907Z","dependency_job_id":null,"html_url":"https://github.com/unix4fun/ic","commit_stats":null,"previous_names":["unix4fun/ac"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/unix4fun/ic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unix4fun%2Fic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unix4fun%2Fic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unix4fun%2Fic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unix4fun%2Fic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unix4fun","download_url":"https://codeload.github.com/unix4fun/ic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unix4fun%2Fic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30457998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T03:55:51.346Z","status":"ssl_error","status_checked_at":"2026-03-13T03:55:33.055Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto","go","golang","irc","irc-client","irc-encryption","plugin","python","weechat"],"created_at":"2025-12-15T09:10:16.707Z","updated_at":"2026-03-13T04:31:12.975Z","avatar_url":"https://github.com/unix4fun.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# PROJECT IS NOT MAINTAINED AND OBSOLETED BY A REWRITE\n# [git.sr.ht/~eau/wic](https://git.sr.ht/~eau/wic)\n# PLEASE USE WIC INSTEAD\n\n# **I**(rc) **C**(rypto) 4 Fun= IC4F\n\n[![Join the chat at https://gitter.im/ic4f/Lobby](https://badges.gitter.im/ic4f/Lobby.svg)](https://gitter.im/ic4f/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n[![Build Status](https://travis-ci.org/unix4fun/ic.svg?branch=master)](https://travis-ci.org/unix4fun/ic)\n\n## Pitch (it's A WORK IN PROGRESS)\n\nIn these time of buzzwords and massive crypto marketing, everybody claim security, inviolability, super crypto guruness, etc.. etc.. \nwe don't but we do try to provide a simple solution to our own humble needs, encrypt IRC chat that we use daily in a relatively safe \nand simple fashion.\n\nThis is an attempt to provide an (to use and maintain) IRC encryption mechanism with an irc client we like, hopefully better than plaintext and current used/existing ones..  with (hopefully) not too much \"false\" sense of security.\n\nIt is inspired from previous/known/alternative projects that has been done by \"pioneers\"/\"hackers\" in underground and take account that IRC have some *limitations*.\n(understand don't yell : IT SUCKS! USE OTR! please read and think first)\n\nFirst project in an inspiring and pragmatic new language : Go\n\n## This Package\n* the IC pipe/tool: 'ic'\n* client script (weechat)\n\n## Goals\n\n* IRC encryption.\n* KISS.\n* Reliable.\n* Small.\n* As safe as I could make it.\n\nI needed something like this *up-to-date* so I tried to do/build it.\n\n\n## Ideas\n\nSo far the design is fairly straight forward, the IRC client itself should/does not have any cryptographic knowledge.\n\nthe client script [ic-weechat](https://github.com/unix4fun/ic/client-scripts/weechat/ic-weechat) just *request* services to a little *daemon* running and\ncommunicating on *stdin/stdout/stderr* using JSON serialization.\n\nThe IRC script running on the client *request* one of the following:\n- generate an ephemeral ECC 25519 assymetric key pair for *my nickname/serv* \n- generate a symmetric key for *chan/serv*\n- add the following public key for [nick] \n- list received \u0026 stored public key(s)\n- encrypt [plaintext] for [chan/serv]\n- decrypt [ciphertext] from [chan/serv]\n- seal a KEX (Key EXchange / ECDH w/ NaCL) for *nick* (using's *nick*'s public key) on *chan/serv* (exchange the symmetric key for *chan/serv*)\n- open a KEX blob from *nick* on *chan/serv* (receive \u0026 open the key exchange blob from *nick*, now ready to encrypt on *chan/serv*)\n\nThis way the IRC client and its scripts does not store any secret, nor deal with encryption mechanisms, it works *in-memory* only and do NOT store anything on disk.\nBut you can save all your *channels/serv* keys on disk for re-using later.\n\n\n## Requirements:\n\n* protobuf-2.6.1+ (if you need to regenerate the go part)\n* go-1.5+ (svn, mercurial, git along with go in fact.. / it works compile with go1.2+ but I want to be able to use go generate which is present since 1.4 release, so let's use it...)\n* weechat 1.3+\n\n(go get should do the rest of the magic...)\n\n## Building/Installing\n\nBuilding is done with the `go` tool. If you have setup your GOPATH\ncorrectly, the following should work:\n\n    go get github.com/unix4fun/ic\n\nif any issues occurs, just :\n\n    cd $GOPATH/src/github.com/unix4fun/ic\n    go generate\n    go build\n    go install\n\nor fill up a github issue so we can investigate and fix.\n\nBinary `ic` should then be in `$GOPATH/bin`\n\n    cd $GOPATH/src/github.com/unix4fun/ic \u0026\u0026 make install\n\nIt will copy the following files into :\n\n    ~/.weechat/python/autoload/ic-weechat.py\n\n## Usage\n\n\n### Let's start\n\n3 main commands:\n\n    /pk\n    '/pk' is used to manage Public Keys (ECC key exchange)\n\n    /sk\n    '/sk' is used to manage Secret Keys (channel/query keys)\n\n    /ic\n    '/ic' is used to enable disable crypto on a specific (weechat) buffer and main script commands\n\nthe flow is simple, when you join the channel, you **GENERATE** \u0026 **BROADCAST** your public key, so that other channel members are aware of your public key,\nother channel members should also **BROADCAST** their own key, a channel member **GENERATE A SECRET** (or already have the) key for the current channel \nto then **EXCHANGE** the (newly created) secret key with other members.\n\n\n_GENERATE A KeyPair_\u0026 _BROADCAST Public Key_|_Public Key Help_\n----------|-----------|\n/pk gen   | /pk help\n\n\n_GENERATE Symmetric Key_|_Send K(ey)EX(change)_|_Receive K(ey)EX(change)_|_Secret Key Help_\n-------------------|----------|-----------------|----------------\n/sk gen {someinput} | /sk give {nickname}|/sk use | /sk help\n\n### I arrive on a new channel, not encrypted\n\nEverything is loaded, you connect irc, and join #prout, #prout is NOT encrypted,\nyes you just joined, so type:\n\n    /sk gen \u003csome keyboard garbage input\u003e\n\nyou will then notice a red bar appearing above your regular status bar, it means\nthe current weechat buffer is *ENCRYPTED*.\n\nIf you type all messages for #prout will be *ENCRYPTED*, if you do need to speak\nin plaintext again, type /ic to toggle encryption of that buffer on and off\n\n\n### I arrive on a new channel, but it is already encrypted, I cannot read\n\nSo you don't have the key, there is not \"automatic\" requests or such, you need\nsomeone to give you the channel (/shared) key to be able to read the\nconversations\n\nSo first generate \u0026 broadcast an ephemeral key pair (AS A KEY *RECEIVER*): \n\n    /pk\n\nNow, someone on the channel who has the channel key, has to pass it to you, here is how. \nGenerate an ephemeral key pair (AS A KEY *HOLDER*) and broadcast your public key:\n    \n    /pk\n\nGive the current buffer/channel key (AS A KEY *HOLDER*):\n\n    /sk give \u003cdestnickname\u003e\n\n\n\nYou will see you have received a Key EXchange payload, you can decide to ignore it or to\nreceive the key for the current buffer (AS A KEY *RECEIVER*):\n\n    /sk use\n\n\nNow you can chat encrypted with your friends, that's it! :)\n\n\nUse /pk help, /sk help or /ic help to access the help.\n\n## Featuring (because there is always a star in your production..)\n\n* [NaCL ECC 25519] (http://nacl.cr.yp.to/install.html) box/secretbox [Go implementation](https://godoc.org/code.google.com/p/go.crypto/nacl) with AEAD (using Salsa20 w/ Poly1305 MAC)\n* [PBKDF2] (http://en.wikipedia.org/wiki/PBKDF2) for key generation using input entropy (/sk gen|CT_ADD script command)\n* [HMAC KDF] (http://en.wikipedia.org/wiki/Key_derivation_function) using SHA-3 (w/ a salt for key based on crypto/rand Go implementation)\n* [SHA-3] (http://en.wikipedia.org/wiki/SHA-3) in various area, including NONCE generation (low probability of collision property)\n* [Go] (http://golang.org) because I like trying something new and promising.\n* [Weechat] (http://weechat.org/) because I like trying something new and promising.\n\n## Known Weaknesses\n\n* no [PFS] (http://en.wikipedia.org/wiki/Perfect_Forward_Secrecy)\n* Evil IRC server MITM wins. (will be fixed with identity keys)\n* [Go crypto implementation] (https://godoc.org/code.google.com/p/go.crypto): is it safe?\n* [EC Curve 25519] (http://cr.yp.to/ecdh.html): is it really safe? \n* memory is swappable to disk and not encrypted (**yet**).\n\n## Ordered TODO:\n\n* unit/regression testing in Go (bleh_test.go).\n* add AES-GCM as an alternative AEAD (In addition to NaCL poly1305/salsa20)\n* benchmark and code cleanup, huge code cleanup.\n* identity RSA/Ed25519 keys (currently in study/dev) with ala SSH authorized_nicks (for trusted KEX/messages).\n* document JSON protocol for other IRC client plugin writers\n* rename a SKMap key (for queries automagically on nick change)\n* rename a PKMap key (on nick change)\n* evaluate feasibility of socialist milionnaire probleme implementation (like OTR).\n* try to avoid page to disk memory\n* scrub memory before deleting the objects\n* check/audit/fuzz source code\n* daemon protobuf ping heartbeat\n* irssi plugin/script.\n\n\n## Done\n* encrypted runtime memory key storage (done but not clean)\n* load/save channel/query keys on disk (using AES-GCM 256 in \"adapted\" PEM format)\n* fix IRC truncated encrypted messages (done but not clean)\n\nThe daemon is implemented in Go langage and will produce a binary.\n\n## Design/Format\n\n(IRC network) \u003c=\u003e IRC Client \u003c--stdin/stdout--\u003e IC --\u003e [infamous crypto keys]\n\n### IRC Message Format:\n```\n\u003cac\u003e [base64_blob]         : Encrypted Messages\n\u003cacpk\u003e [base64_blob]       : Public key Messages\n\u003cackx:nick\u003e [base64_blob]  : KEX Messages\n```\n\n\n### Channel/Query Key Generation:\n```\n\u003cCHANNEL_KEY\u003e is built the following way:\n HKDF_SHA3-256(\n         secret:\u003cPBKDF_SHA3-256_GENERATOR\u003e, \n         salt:\u003cCRYPTO_RAND_256\u003e, \n         info:\u003cSHA3_INFO\u003e\n )\n\nwhere \u003cPBKDF_SHA3-256_GENERATOR\u003e is :\n PBKDF2_SHA3-256(\n         pass:\u003cUSER_INPUT\u003e, \n         salt:\u003cCRYPTO_RAND_256\u003e, \n         iteration:4096,\n         len:32\n )\n\nand \u003cSHA3_INFO\u003e is:\n SHA3(\u003cserver_name\u003e||':'||\u003cnickname\u003e||':'||\u003cchannel_name\u003e)\n\n```\n\n### Encrypted Messages Format:\n```\nBase64(\n        'ACheader' ||\n        \u003cNonceInt32Value\u003e ||\n        NACL_SEAL(\n            plain: Zlib(\u003cPlaintext\u003e)\n            nonce: \u003cNONCE_AUTH\u003e,\n            key: \u003cCHANNEL_KEY\u003e,\n        ) \n)\n\nwhere \u003cNonceInt32Value\u003e is:\n a non repeating 32bit counter starting at 0, for each new channel key.\n\nwhere \u003cNONCE_AUTH\u003e is:\n SHA3( SHA3('CHANNEL') || \n       ':' || \n       SHA3('SRC_NICK') || \n       ':' || \n       SHA3('NONCE_VALUE') || \n       ':' || \n       SHA3('ACheader')\n )\n\n```\n\n\n### Public Key Messages Format:\n```\nBase64(\n        'PKheader' ||\n        Zlib(\u003cNACL_PUBKEY\u003e)\n)\n```\n\n### KEX Messages Format: \n```\nTODO\n```\n\nkeys should never appear in clear and should be \"randomly\" (as far as my crypto user knowledge goes) generated.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funix4fun%2Fic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funix4fun%2Fic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funix4fun%2Fic/lists"}