2013-05-08 8 views
9

here से मैं समझता हूं कि बीएन_ सीटीएक्स एक संरचना है जिसमें बिग्नो अस्थायी चर होते हैं। उन BIGNUM चर कब बीएन_सीटीएक्स के BN_POOL दर्ज करेंगे? अगर मैं एक bignum_ctx BN_CTX *ctx; (या तो मेरी समारोह के शीर्ष पर घोषित, या एक तर्क के रूप में पारित कर दिया), है जब मैंओपनएसएसएल बीएन_ सीटीएक्स उपयोग

ctx = BN_CTX_new(); 
/* Do something */ 
BN_CTX_free(ctx); 

करना चाहिए और इसके बजाय निम्नलिखित है जब मैं क्या करना चाहिए?

BN_CTX_start(ctx); 
/* Do something */ 
BN_CTX_end(ctx); 

और मैं एक bignum BIGNUM *bn;, क्या में हालात मैं

BN_CTX_start(ctx); 
bn = BN_CTX_get(ctx); 
BN_CTX_end(ctx); 
सिर्फ नए और उदाहरण के बजाय

का उपयोग करना चाहिए है या नहीं?

bn = BN_new(); 
if (bn) 
    BN_free(bn); 

उत्तर

15

यहां मैं अपने स्वयं के प्रश्न का उत्तर दे रहा हूं। मुझे लगता है कि यह एसओ में हर समय होता है।

ओपनएसएसएल में बीआईजीएनएन एक जटिल संरचना है जो मनमाने ढंग से बड़ी संख्या रखती है, और इसलिए बार-बार बीआईजीएनएन उदाहरण बनाने और मुक्त करने के परिणामस्वरूप काफी ओवरहेड होगा। BIGNUM संदर्भ, या BN_CTX, इस ओवरहेड को सहेजने के लिए बनाया और उपयोग किया जाता है। BN_POOL और BN_STACK:

संरचना

BN_CTX संरचना दो संरचनाओं में शामिल है। BN_POOL एक लिंक-सूची के साथ अस्थायी bignums का एक बंडल रखता है, जबकि BN_STACK ढेर फ्रेम का प्रबंधन करता है।

पर बनाएं

एक BN_CTX उदाहरण ctxBN_CTX_new() साथ बनाया जाता है। पहले एक नया स्टैक फ्रेम प्राप्त करने के लिए एक फ़ंक्शन को BN_CTX_start() पर कॉल करना होगा। BN_CTX_get(ctx) पर कॉल करके, ओपनएसएसएल ctx में एक अप्रयुक्त बिग्नम की तलाश करता है। यदि कोई उपलब्ध टेम्पल बिग्नम नहीं है, तो ओपनएसएसएल एक बना देगा और लिंक्ड-लिस्ट से लिंक करेगा। यह ctx को अन्य कार्यों के तर्क के रूप में पारित करने से पहले किया जाना चाहिए।

बेशक उपयोगकर्ता को बहुत अधिक अस्थायी बिग्नम बनाने से रोकने के लिए एक तंत्र है। BN_POOL के भीतर आप बना सकते हैं की पूर्वनिर्धारित संख्या 16 है। एक बार सीमा पार हो जाने के बाद, संभावित सेगमेंटेशन गलती ओपनएसएसएल लाइब्रेरी में यादृच्छिक स्थान पर होगी।

बाहर निकलें

समारोह के बाद पर bignum उदाहरण यह ctx से मिला है और बाहर निकलने के लिए तैयार है के साथ किया जाता है, BN_CTX_end() अस्थायी bignums जारी करने के लिए कहा जाता है, जिसका अर्थ है कि इन bignums बन "अप्रयुक्त" और हो सकता है अगले BN_CTX_get() द्वारा अनुरोध किया गया।

अंत में, शायद BN_CTX_start() और BN_CTX_end() की कई बार के बाद, BN_CTX_end()BN_POOL में BN_STACK संरचना, और स्पष्ट नि: शुल्क bignums मुक्त करने के लिए कहा जाता है।

उदाहरण कोड

void foo(){ 
    BN_CTX* ctx; 
    ctx = BN_CTX_new(); 

    /* Using BIGNUM context in a series of BIGNUM operations */ 
    bar(ctx); 
    bar(ctx); 
    bar(ctx); 

    /* Using BIGNUM context in a function called in loops */ 
    while(/*condition*/){ 
     bar(ctx); 
    } 

    BN_CTX_free(ctx); 
} 

और यहाँ समारोह bar()

void bar(BN_CTX* ctx){ 
    BIGNUM *bn; 
    BN_CTX_start(ctx); 
    bn = BN_CTX_get(ctx); 

    /* Do something with bn */ 

    BN_CTX_end(ctx); 
} 

समारोह foo() एक नया bignum संदर्भ बनाता है और तर्क bar() कार्य करने के लिए के रूप में इसे पारित है। पहली बार bar()BN_CTX_get() पर कॉल करता है, एक अस्थायी बिग्नम BN_POOL में बनाया और संग्रहीत किया जाता है और वापस कर दिया जाता है। BN_CTX_get() के बाद के bar() में नया बिग्नम नहीं बनाया जाएगा बल्कि इसके बजाय इसे पहले स्थान पर बनाया गया है।में यह अस्थायी बिग्नम अंततः BN_CTX_free() द्वारा स्पष्ट रूप से मुक्त हो जाएगा।

निष्कर्ष

जब प्रदर्शन चिंता का विषय है, यह काम करता है कि

  1. bignum संरचनाओं की आवश्यकता अस्थायी बड़ी संख्या धारण करने के लिए करने के लिए पारित करके bignum निर्माण के भूमि के ऊपर बचाने के लिए BN_CTX उपयोग करें, और
  2. को कुछ बिग्नम ऑपरेशंस करने के लिए अनुक्रमिक रूप से कहा जाता है, या
  3. बार-बार लूप में बुलाया जाता है।

ध्यान रखें कि BN_CTX में संग्रहीत बिग्नम की संख्या के लिए एक सीमा है। यदि प्रदर्शन कोई मुद्दा नहीं है, तो

bn = BN_new(); 
if (bn) 
    BN_free(bn); 

का उपयोग ठीक है।

+1

के लिए स्टैक फ्रेम क्या है? – updogliu

+0

चूंकि एक बीएन_ सीटीएक्स ऑब्जेक्ट 'सीटीएक्स' को फ़ंक्शंस से फ़ंक्शन तक पास किया जा सकता है, इसलिए स्टैक फ्रेम इन फ़ंक्शन कॉल की गहराई को ट्रैक करने के लिए उपयोग की जाने वाली जानकारी का एक गुच्छा है (जो' ctx' को तर्क के रूप में पास करता है), और आवंटित स्मृति का आकार 'ctx'। – ChiaraHsieh

+0

मुझे लगता है कि यह फ़ंक्शन द्वारा tmp चर के फ़ंक्शन को रिलीज़ करने के लिए है। यदि कोई फ़ंक्शन दो tmp BIGNUMs 'bn1 = BN_CTX_get (ctx) का उपयोग करता है; बीएन 2 = बीएन_ सीटीएक्स_एजीटी (सीटीएक्स); 'बीएन 1' जारी करने के लिए कोई तरीका नहीं है (लेकिन मुझे नहीं 'बीएन 2'। उन्हें केवल BN_CTX_end पर एक साथ रिलीज़ किया जा सकता है। स्टैक फ्रेम जानकारी यह याद रखना है कि यह फ़ंक्शन दो tmps 'bn1' और' bn2' का उपयोग कर रहा है, मुझे लगता है। – updogliu

संबंधित मुद्दे