18. 6. 2014

RSA šifrování a dešifrování v Pythonu

Asymetrická šifra RSA je založena na výpočtech mocnin v modulární aritmetice. Pokud máme modulus n, šifrovací exponent e a dešifrovací exponent d, pak šifrovanou zprávu me získáme z původní zprávy m0 takto:

me = m0e mod n

Zašifrovanou zprávu dešifrujeme podobně:

md = med mod n

V Pythonu máme k dispozici funkci pow, která umí počítat mocniny mimo jiné i v modulární aritmetice. Ukažme si příklad s konkrétními hodnotami.

Mějme následující modulus:

n = 21527780186004234447971732039802273528579441854351817770636417084074045726916755811452176780972972762465425067238626216467850161245907157490982001685910067508063834571557543426677191033339325440982101764581246164671034032604464829492680255606381797121955207928235115958807472977713204039171154535203439165945886770314300527479967151239790376461172721498826129973777800192746896042404231774774252977582877970999073179147617119355023510142421028451033729206425509932433205750495464400915358156290323467181810120864844047779571069775054986909028190660734157823936101832243439927710101844604725375998277508273471747760851

Mějme následující šifrovací exponent:

e = 65537

Mějme následující dešifrovací exponent:

d = 1923924020773407405919868693365914156230675663227468402316515782861920530731517139748163623695907677644078835143760528401547193103396222308385821503492306107919646597885355323711007642740260144770620718604030681698555721637614637629714943575180099573420993527864764547823906636410977555540007203757977069364532082494093469869831565142548516157723340358656083422963282407247035204429319739217882469055600881431028253761271632041603247673621782328799866497497713708052433725288995340158616357124872463424481146842480686008560113218230274213908368506451031670836819663288989296709347723856301791343486712693995705188017

A mějme nějakou zprávu:

mo = 123456789

Tuto zprávu zašifrujeme a zobrazíme:

me = pow(mo, e, n)
print me

1923924020773407405919868693365914156230675663227468402316515782861920530731517139748163623695907677644078835143760528401547193103396222308385821503492306107919646597885355323711007642740260144770620718604030681698555721637614637629714943575180099573420993527864764547823906636410977555540007203757977069364532082494093469869831565142548516157723340358656083422963282407247035204429319739217882469055600881431028253761271632041603247673621782328799866497497713708052433725288995340158616357124872463424481146842480686008560113218230274213908368506451031670836819663288989296709347723856301791343486712693995705188017

Zašifrovanou zprávu dešifrujeme a zobrazíme:

md = pow(me, d, n)
print md

123456789

Dešifrovaná zpráva je shodná se zprávou původní.

17. 6. 2014

Rozmařilá

Nalili si
do lavoru
irskou whisky
z Tullamoru.

Teď si v klidu
dáti mohou
nejdražší to
koupel nohou.

5. 6. 2014

Třídy a objekty v jazyce Lua

Programovací jazyk Lua, přestože jako jediný složený datový typ nabízí tabulky, umožňuje i objektové programování. Klasický příklad lze nalézt v Programming in Lua : 16.2:

Account = {balance = 0}

function Account:new (o)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  return o
end
    
function Account:deposit (v)
  self.balance = self.balance + v
end
    
function Account:withdraw (v)
  if v > self.balance then
    error"insufficient funds"
  end
  self.balance = self.balance - v
end

Takovouto třídu pak můžeme použít následujícím způsobem:

a = Account:new()
a:deposit(1)
a:withdraw(1)

Co přesně se ale odehraje? Pojďme se na to podívat řádek po řádku.

a = Account:new()
  -- nebo také
a = Account.new(Account)

Voláme funkci new z tabulky Account. Této funkci předáváme do self parametru tabulku Account a parametr o zůstává nil. Do proměnné o se dosadí prázdná tabulka a této tabulce se jako metatabulka nastaví Account. Zároveň se Account dosadí sobě do proměnné __index.

a:deposit(1)
  -- nebo také
a.deposit(a, 1)

V tabulce a se hledá funkce deposit, která tam však není, takže se v metatabulce Account najde tabulka __index (což je taktéž Account) a hledá se tam. Funkce je nalezena a zavolána.

Ve funkci deposit se hledá položka self.balance (konkrétně a.balance), která však neexistuje, takže následuje stejná hledací procedura (metatabulka.__index.balance). Nalezená proměnná Account.balance obsahuje nulu a tato hodnota se použije.

Následně se k nalezené hodnotě přičte v a výsledek se dosadí do proměnné self.balance (konkrétně a.balance). Tato proměnná neexistuje a je vytvořena.

a:withdraw(1)
  -- nebo také
a.withdraw(a, 1)

V této funkci používáme položku self.balance (konkrétně a.balance), která však už existuje a rovnou se použije. K žádnému složitému dohledávání už nedochází.

Na první pohled působí zvláštně, že objektová proměnná se nevytváří už v konstruktoru, ale až při prvním dosazení. Do té doby ji zastupuje proměnná ve třídě, která poskytuje výchozí hodnotu. Nicméně výsledné chování je správné a funguje podle očekávání.

Grafické programy v Pythonu

Pro vývoj grafických programů v Pythonu existuje mnoho různých knihoven. Pokud ale na takovou knihovnu začneme klást doplňující požadavky, výběr se nám začne zužovat. Dobrá grafická knihovna by měla:

  • Fungovat pod různými operačními systémy, např. Windows, Linux, Mac OS.
  • Fungovat na 32-bitových i 64-bitových systémech
  • Fungovat s Python 2 i 3
  • Mít snadnou instalaci
  • Mít neomezující licenci
  • Mít aktivní vývoj

Na základně těchto požadavků můžeme vyřadit:

  • TkInter — tyto aplikace nejsou hezké. Opravdu nejsou.
  • WxPython — nefunguje na 64-bitových Windows
  • PyGTK — neprobíhá vývoj
  • PyQt — je omezeno GPL licencí

Takže nám zůstává … PySide. Jedná se o Pythoní nadstavbu nad knihovnou Qt, s LGPL licencí.

Jediným nedostatkem je (prozatím) podpora Qt 5. Ale to se možná časem spraví.

3. 6. 2014

Simulace VHDL pomocí GHDL

Máme-li hardware definovaný pomocí VHDL kódu, můžeme jeho chování simulovat pomocí komerčních nástrojů, např. Altera Quartus, Xilinx ISE nebo Lattice Diamond. Anebo můžeme použít free/open-source program GHDL.

GHDL vytváří ze zdrojových VHDL souborů spustitelné programy a jejich spuštěním následně vznikají soubory s popisem signálů na jednotlivých datových linkách.

Simulace pomocí GHDL sestává z několika kroků, které je šikovné řídit pomocí programu make. Mějme dva moduly cm.vhdl a dm.vhdl, a k nim testovací moduly cm_tb.vhdl a dm_tb.vhdl, kde „_tb“ je zkratka pro „testbench“. Makefile pak může vypadat například takto:

GHDL=ghdl
GHDLFLAGS=

#--------------------------------------
# Execute all simulations
all: cm.vcd dm.vcd

#--------------------------------------
cm.vcd: cm_tb
 # Run unit (= execute)
 $(GHDL) -r $< --vcd=$@

# Target is the simulated entity name
cm_tb: cm.o cm_tb.o
 # Elaborate unit (= link)
 $(GHDL) -e $(GHDLFLAGS) $@

#--------------------------------------
dm.vcd: dm_tb
 # Run unit (= execute)
 $(GHDL) -r $< --vcd=$@

# Target is the simulated entity name
dm_tb: dm.o dm_tb.o
 # Elaborate unit (= link)
 $(GHDL) -e $(GHDLFLAGS) $@

#--------------------------------------
%.o: %.vhdl
 # Analyze file (= compile)
 $(GHDL) -a $(GHDLFLAGS) $<

Výstupem budou soubory cm.vcd a dm.vcd obsahující simulované průběhy signálů. Tyto soubory můžeme zobrazit například pomocí programu gtkwave.