Speck
**Speck**, Haziran 2013'te Ulusal Güvenlik Ajansı (NSA) tarafından halka açık bir şekilde yayınlanmış bir blok şifreleme ailesidir. Speck, yazılım uygulamaları için optimize edilmişken, kardeş algoritması Simon, donanım uygulamaları için optimize edilmiştir. Speck bir add-rotate – xor (ARX) şifresidir.

NSA, 2011 yılında Simon ve Speck şifreleri üzerinde çalışmaya başlamıştır. Ajans, ABD federal hükûmetindeki bazı ajansların kabul edilebilir bir güvenlik seviyesinde, çeşitli Nesnelerin İnterneti cihazlarında iyi çalışacak bir şifreleme algoritmasına ihtiyaç duyacağını öngörmüştür.

Şifrenin tanımı
---------------

Speck çeşitli blok ve anahtar boyutlarını desteklemektedir. Bir blok her zaman iki kelimeden oluşmaktadır, ancak kelime boyutları 16, 24, 32, 48 veya 64 bit olabilirler. Karşılık gelen anahtarlar 2, 3 veya 4 kelimedir. Her tur, sağ kelimenin sol kelimeye eklenmesi, anahtarın sol kelime ile XOR'lanması, sonra da sol tarafın sağ taraf ile XOR'lanması olmak üzere iki yönlüdür. Tur sayısı aşağıdaki parametrelere bağlıdır:

| Blok boyutu (bit) | Anahtar boyutu (bit) | Tur sayısı |
| --- | --- | --- |
| 2 × 16 = 32 | 4 × 16 = 64 | 22 |
| 2 × 24 = 48 | 3 × 24 = 72 | 22 |
| 4 × 24 = 96 | 23 |
| 2 × 32 = 64 | 3 × 32 = 96 | 26 |
| 4 × 32 = 128 | 27 |
| 2 × 48 = 96 | 2 × 48 = 96 | 28 |
| 3 × 48 = 144 | 29 |
| 2 × 64 = 128 | 2 × 64 = 128 | 32 |
| 3 × 64 = 192 | 33 |
| 4 × 64 = 256 | 34 |

Anahtar çizelgesi, ana blok şifresi ile aynı tur fonksiyonunu kullanır.

Referans Kodu
-------------

Aşağıda tasarımcıların önermiş olduğu, 128 bit blok boyutu ve anahtarı olan Speck varyantının C ile yazılmış kodu bulunmaktadır. Burada anahtar = (K [1], K [0]). IACR ePrint'lerinden uyarlanmıştır.

```
#include <stdint.h>

#define ROR(x, r) ((x >> r) | (x << (64 - r)))
#define ROL(x, r) ((x << r) | (x >> (64 - r)))
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x)
#define ROUNDS 32

void encrypt(uint64\_t ct[2],
 uint64\_t const pt[2], 
 uint64\_t const K[2])
{
 uint64\_t y = pt[0], x = pt[1], b = K[0], a = K[1];

 R(x, y, b);
 for (int i = 0; i < ROUNDS - 1; i++) {
 R(a, b, i);
 R(x, y, b);
 }

 ct[0] = y;
 ct[1] = x;
}

```

Bu kodun tur anahtarlarını (Anahtar Çizelgesi) istek üzerine hesapladığını unutmayın. Genelde, diğer blok şifrelemelerde olduğu gibi, tur anahtarları her blok için tekrar tekrar hesaplanmak yerine, bir defa hesaplanıp gerektiğinde kullanılmak üzere saklanmaktadır.

16 bit kelimeler için (Speck32), 7 bit sağa ve 2 bit sol kaydırılmaktadır. Diğer tüm kelime boyutları için, burada kullanıldığı gibi 8 ve 3'tür.

Eğer anahtar 2 kelimeden uzunsa, kaydırmalarda kullanılan 2 veya 3 `a` değeri vardır.

### Endian

Orijinal Speck makalesinde, düz metin bloğu, iki kelime olarak ele alındığı durumlarda bayt sırası açıkça belirtilmemiştir. Makalede verilen test vektörleri *big-endian* sıralamasındadır. Bununla birlikte, makalenin yazarları, bazı geliştiricilere  anahtarların, düz metinin ve şifreli metinin *little-endian* olması gerektiğini önermiştir. Bu öneri diğer geliştiriciler tarafından da dikkate alınmıştır.

Kaynakça
--------

1. 1 2 3  "The SIMON and SPECK Families of Lightweight Block Ciphers". 19 Haziran 2013. 3 Eylül 2013 tarihinde kaynağından arşivlendi. Erişim tarihi: 20 Eylül 2016.
2. ↑  "Simon and Speck: Block Ciphers for the Internet of Things" (PDF). 9 Temmuz 2015. 1 Aralık 2017 tarihinde kaynağından (PDF) arşivlendi. Erişim tarihi: 23 Kasım 2017.
3. ↑  "Re: [PATCH 0/5] crypto: Speck support". *www.mail-archive.com* (İngilizce). 13 Nisan 2018 tarihinde kaynağından arşivlendi. Erişim tarihi: 12 Nisan 2018.
4. ↑  "SPECK – Crypto++ Wiki". *www.cryptopp.com* (İngilizce). 13 Nisan 2018 tarihinde kaynağından arşivlendi. Erişim tarihi: 12 Nisan 2018.