प्रिमिटिव और इंटरफ़ेस

अब हम Tink में इस्तेमाल होने वाली भाषा के दो अहम हिस्सों प्रिमिटिव और इंटरफ़ेस को कहते हैं. पहले उन्हें अनौपचारिक तौर पर, लेकिन फिर औपचारिक तौर पर परिभाषित किया गया.

प्रिमिटिव

प्रिमिटिव एक गणितीय ऑब्जेक्ट होता है. यह सभी एल्गोरिदम के हिसाब से होता है, जो कोई काम सुरक्षित तरीके से करता है. उदाहरण के लिए, AEAD प्रिमिटिव में सभी एनक्रिप्शन एल्गोरिदम होते हैं, जो Tink की ज़रूरत वाली सुरक्षा प्रॉपर्टी को पूरा करते हैं.

हम इस बात पर ज़ोर देते हैं कि प्रिमिटिव किसी प्रोग्रामिंग भाषा या उन्हें ऐक्सेस करने के किसी खास तरीके से बाध्य नहीं हैं. इसके बजाय, आपको प्रिमिटिव को पूरी तरह से गणितीय ऑब्जेक्ट की तरह समझना चाहिए. उदाहरण के लिए, अगर हम AEAD पर विचार करते हैं, तो बुनियादी तौर पर इसमें फ़ंक्शन के जोड़े होंगे, एक जो एन्क्रिप्शन करता है, और दूसरा जो डिक्रिप्शन करता है.

इंटरफ़ेस

इंटरफ़ेस एक ऐसा तरीका है जिससे हम उपयोगकर्ताओं को प्रीमिटिव का ऐक्सेस देते हैं. उदाहरण के लिए, हमें उम्मीद है कि आने वाले समय में Tink में Mac का इंटरफ़ेस होगा. हालांकि, StreamingMac इंटरफ़ेस की मदद से, डेटा के Mac का हिसाब भी लगाया जा सकता है, जो सीधे मेमोरी में लोड नहीं होता.

ध्यान दें कि हम यहां इंटरफ़ेस और प्रिमिटिव में साफ़ तौर पर अंतर करते हैं. इससे साफ़ तौर पर पता चलना चाहिए कि ये दोनों इंटरफ़ेस, गणित से जुड़े जिस ऑब्जेक्ट को ऐक्सेस देते हैं वह एक ही है.

औपचारिक परिभाषाएं

ज़्यादातर पाठकों के लिए, ऊपर दी गई सहज जानकारी काफ़ी हो सकती है. फिर भी, हमें लगता है कि कभी-कभी इन सिद्धांतों की औपचारिक परिभाषाएं देना ज़रूरी हो सकता है.

क्रिप्टोग्राफ़िक फ़ंक्शन

क्रिप्टोग्राफ़िक फ़ंक्शन का सिद्धांत, प्रिमिटिव की अवधारणा जितना ज़रूरी नहीं है. हालांकि, हमें इसे औपचारिक रूप से प्रिमिटिव को परिभाषित करने के लिए पेश करना होगा.

क्रिप्टोग्राफ़िक फ़ंक्शन

क्रिप्टोग्राफ़िक फ़ंक्शन एक मैप होता है

\[ f: {\bf K} \times {\bf R} \times {\bf I} \to {\bf O}\]

किसी सेट से \({\bf K}\) (की स्पेस), एक सेट \({\bf R} = \{0,1\}^{\infty}\) (रैंडमनेस, जिसे हम इनफ़ाइनाइट बिटस्ट्रिंग का सेट मानते हैं), और एक सेट \({\bf I}\) (इनपुट स्पेस), एक सेट \({\bf O}\) (आउटपुट स्पेस).

यह बाद में साफ़ हो जाएगा कि हमने कोई खास रैंडमनेस पैरामीटर क्यों जोड़ा है.

उदाहरण के तौर पर, हम एक संभावना दिखाते हैं कि इन सिद्धांतों को AES-GCM पर कैसे मैप किया जा सकता है. कुंजी के हर मान्य साइज़ \(s_k\), नॉन्स साइज़ \(s_n\), और टैग साइज़ \(s_t\)के लिए, AES-GCM में दो क्रिप्टोग्राफ़िक फ़ंक्शन होते हैं. इनमें से एक, एन्क्रिप्ट (सुरक्षित) करने के लिए और दूसरा डिक्रिप्शन के लिए होता है. दोनों में एक ही मुख्य स्पेस होगा \({\bf K} = \{0,1\}^{s_k}\).

एन्क्रिप्ट (सुरक्षित) करने के फ़ंक्शन \(\mathrm{Enc}\)के लिए, नॉन्स को चुनने के लिए रैंडमनेस के पहले \(s_n\) बिट का इस्तेमाल किया जाएगा.

चलिए \({\bf B} = \{0,1\}^8\) एक बाइट दिखाते हैं. एन्क्रिप्ट (सुरक्षित) करने के फ़ंक्शन का इनपुट स्पेस, आर्बिट्रेरी लंबाई वाले बाइट स्ट्रिंग के जोड़ों का \({\bf I} = {\bf B}^{*} \times {\bf B}^{*}\) जोड़ होता है. पेयर का पहला एलिमेंट मैसेज होता है और दूसरा एलिमेंट, इससे जुड़ा डेटा होता है. AES-GCM मानक में इनपुट की लंबाई के लिए ऊपरी सीमा तय की गई है, लेकिन हम मनचाहे तरीके से लंबाई की अनुमति देना पसंद करते हैं और इसके बजाय आउटपुट स्पेस में एक खास गड़बड़ी का निशान \(\bot\) जोड़ देते हैं. इसके बाद, आउटपुट स्पेस \({\bf O} = {\bf B}^* \cup \{\bot\}\)बन जाता है, जहां हम सफल कंप्यूटेशन के नतीजे को, स्टैंडर्ड में दिए गए \((\mathrm{IV} \| \mathrm{ciphertext} \| \mathrm{tag})\) और आउटपुट के तौर पर तय करते हैं. अगर कुछ इनपुट बहुत लंबा है, तो नतीजे\(\bot\)के तौर पर तय किए जाते हैं. इसलिए, किसी तय कुंजी के लिए, एन्क्रिप्ट (सुरक्षित) करने का फ़ंक्शन \(\mathrm{Enc}_k : {\bf R} \times {\bf B}^* \times {\bf B}^* \rightarrow {\bf B}^* \cup \{\bot\}\)का टाइप बन जाता है.

डिक्रिप्शन फ़ंक्शन के लिए \(\mathrm{Dec}\) की स्पेस एक जैसा होता है. इनपुट स्पेस एक जैसा है: \({\bf I} ={\bf B}^* \times {\bf B}^*\), लेकिन अब पहला एलिमेंट, एन्क्रिप्शन फ़ंक्शन का आउटपुट है. वहीं, दूसरा एलिमेंट अब भी उससे जुड़ा डेटा है.

आउटपुट स्पेस भी ऐसा ही होता है \({\bf O} = {\bf B}^* \cup \{\bot\}\) (फिर से, इत्तिफ़ाक़ है). इसका मतलब कुछ हद तक अलग है, क्योंकि \(\bot\) आम तौर पर, पुष्टि करने में हुई गड़बड़ी को दिखाता है. हालांकि, कुछ इनपुट बहुत लंबे होने पर भी यह आउटपुट वाली स्थिति ही होगी.

इस बात पर ज़ोर दिया जाता है कि ऊपर बताए गए तरीके से सिर्फ़ स्टैंडर्ड को औपचारिक बनाने का विकल्प नहीं है. उदाहरण के लिए, नॉन्स को रैंडमनेस से पढ़ने के बजाय इनपुट के हिस्से को नॉन्स माना जा सकता है (जिससे बहुत अलग प्रिमिटिव मिलता है). इसके अलावा, आउटपुट को नॉन्स, साइफ़रटेक्स्ट, और टैग (कॉन्सटेनेशन के बजाय) वाले तीन गुना के रूप में परिभाषित किया जा सकता है. इसके अलावा, कोई दूसरा व्यक्ति मुख्य स्पेस को (कुछ हद तक स्वेच्छा से) \({\bf K} = \{0,1\}^{128} \cup \{0,1\}^{256}\)तक सीमित कर सकता है.

क्रिप्टोग्राफ़िक एल्गोरिदम:

ए (सिमेट्रिक) क्रिप्टोग्राफ़िक एल्गोरिदम एक टपल है

\[(f_1, ... f_k)\]

हैं, जिनमें सभी फ़ंक्शन की मुख्य जगह एक ही होती है. क्रिप्टोग्राफ़िक एल्गोरिदम का टाइप एक टपल है \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\).

उदाहरण के लिए, 'कुंजी', नॉन्स, और टैग साइज़ के हर मान्य ट्रिपल \((s_k, s_n, s_t)\) के लिए, AES-GCM\({}_{s_k, s_n, s_t}\) एक क्रिप्टोग्राफ़िक एल्गोरिदम है. इसमें दो फ़ंक्शन हैं \(\mathrm{Enc}\) और \(\mathrm{Dec}\) इसके बारे में ऊपर बताया गया है.

प्रिमिटिव और इंटरफ़ेस

अब हम एक क्रिप्टोग्राफ़िक प्रिमिटिव को तय करते हैं.

प्रिमिटिव
प्रिमिटिव, क्रिप्टोग्राफ़िक एल्गोरिदम का एक सेट होता है. इसमें सभी एल्गोरिदम का टाइप एक ही होता है \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\)और एल्गोरिदम की मुख्य जगहें, जोड़ी के हिसाब से अलग-अलग होती हैं.

उदाहरण के लिए, टिंक में \(\mathrm{AEAD}\) प्रिमिटिव हो. इसमें कई एल्गोरिदम हैं. इनमें, कुंजी के साइज़ 128 और 256 बिट के लिए AES-GCM, नॉन्स साइज़ 96 बिट, कुछ मुख्य साइज़ के साथ AES-EAX, और XChaCha20Poly1305 शामिल हैं. इनमें मुख्य स्पेस अलग-अलग हैं, लेकिन सभी में एक जैसे क्रिप्टोग्राफ़िक फ़ंक्शन हैं \(\mathrm{Enc}\) और \(\mathrm{Dec}\). (हमें इस औपचारिक चर्चा में AES-GCM के अलग-अलग कुंजी साइज़ को छोटा करने का कोई मकसद नहीं दिखता, लेकिन बेशक कोई एक ऐसा कर सकता है).

प्रिमिटिव की परिभाषाएं

प्रिमिटिव के बारे में सोचने का सामान्य तरीका सबसे पहले क्रिप्टोग्राफ़िक फ़ंक्शन के गुणों को परिभाषित करना है. इसके बाद, इन सभी एल्गोरिदम को सिर्फ़ ऐसा माना जाना चाहिए जिससे इन दोनों का इस्तेमाल किया जाए.

उदाहरण के लिए, AEAD के लिए हम कहेंगे कि \(\mathrm{Dec}_k(\mathrm{Enc}_k(m, a), a) = m\) 'हमेशा' संतुष्ट है (उदाहरण के लिए, अगर सादा टेक्स्ट \(m\) बहुत लंबा हो). इसके अलावा, हमारे पास सुरक्षा से जुड़ी प्रॉपर्टी भी हैं. उदाहरण के लिए, किसी रैंडम कोड के लिए, एन्क्रिप्ट (सुरक्षित) करना पूरी तरह से सुरक्षित होता है.

इसके बाद, AEAD प्रिमिटिव, उन सभी क्रिप्टोग्राफ़िक एल्गोरिदम का सेट होता है जो इन प्रॉपर्टी के लिए काम करते हैं. दूसरे शब्दों में, जब हम किसी प्रिमिटिव को तय करते हैं, तो इसे प्रॉपर्टी के आधार पर तय करते हैं. जैसा कि परिभाषा में बताया गया है, हम एल्गोरिदम की सूची नहीं देते.

इंटरफ़ेस

Tink में इंटरफ़ेस से एक प्रिमिटिव का ऐक्सेस मिलता है. यह इनपुट स्पेस से आउटपुट स्पेस के किसी एलिमेंट को कंप्यूट करने में मदद करता है. उदाहरण के लिए, Java में AEAD इंटरफ़ेस देखें:

public interface Aead {
  byte[] encrypt(byte[] plaintext, byte[] associated_data) throws GeneralSecurityException;
  byte[] decrypt(byte[] ciphertext, byte[] associated_data) throws GeneralSecurityException;
}

ध्यान दें कि हम रैंडमनेस का ऐक्सेस नहीं देते. इसके बजाय, हम उपयोगकर्ता को इनपुट स्पेस के एलिमेंट उपलब्ध कराने की अनुमति देते हैं. रैंडमनेस के ऐक्सेस पर रोक लगाना, बेशक मक़सद से होता है.1

Tink में कभी-कभी एक प्रिमिटिव के लिए कई इंटरफ़ेस मिलते हैं. यह बहुत काम का हो सकता है, क्योंकि कभी-कभी ज़रूरतें अलग-अलग हो सकती हैं. इसके बावजूद, ऐसा करने के लिए पैसे देने पड़ते हैं: आम तौर पर, जितने ज़्यादा इंटरफ़ेस एक साथ उपलब्ध होते हैं, इंटरऑपरेबिलिटी उतनी ही कम होती है. उदाहरण के लिए, मान लें कि कोई व्यक्ति Tink पर आधारित एक लाइब्रेरी लिखता है, जिसके लिए उपयोगकर्ता को Aead ऑब्जेक्ट (अंदरूनी कुछ एन्क्रिप्ट करने के लिए) पास करना पड़ता है. अगर Tink में \(\mathrm{AEAD}\) प्रिमिटिव में, बहुत ज़्यादा अलग-अलग इंटरफ़ेस हों, तो इस बात की संभावना बढ़ जाती है कि उपयोगकर्ता के पास ऐसा इंस्टेंस तैयार न हो जो उपयोगकर्ता के चुने गए कुंजी और लाइब्रेरी के लिए एक साथ काम करे. इसलिए, और-ज़्यादा इंटरफ़ेस जोड़ना इसमें कोई परेशानी नहीं होती.


  1. AEAD साइफ़र में यह प्रॉपर्टी होती है कि वे चुने गए साइफ़रटेक्स्ट हमलों से सुरक्षित होते हैं. इस बात की गारंटी सिर्फ़ तब होती है, जब नॉन्स का दोबारा इस्तेमाल न किया गया हो. Tink में Aead इंटरफ़ेस को इस तरह से डिज़ाइन किया गया है कि यह नॉन्स के इस्तेमाल को रोकता है: उपयोगकर्ता एन्क्रिप्शन के लिए इनपुट के तौर पर नॉन्स नहीं दे सकता. इसके बजाय, एन्क्रिप्ट (सुरक्षित) करने के हर तरीके के लिए एक नया नॉन्स रैंडम तरीके से जनरेट किया जाता है.