Score:2

การจัดเก็บ R^2 ด้วยรหัสสาธารณะมีประโยชน์อย่างไร

ธง in

ฉันคิดว่าฉันได้ทำวิศวกรรมย้อนกลับคีย์สาธารณะของ Samsung RSA สำเร็จแล้ว ที่นี่. อย่างไรก็ตาม คีย์สาธารณะส่วนใหญ่ดูเหมือนจะประกอบด้วยโมดูลัส แต่ก็ประกอบด้วยจำนวนเต็ม 32 บิตด้วย -1 / n[0] สมัย 2^32เช่น คำผกผันของคำ 32 บิตแรกของโมดูลัสและ R^2 (อาจเป็น mod n?)

ใครช่วยอธิบายได้ว่าทำไมค่าเหล่านี้จึงรวมอยู่ในคีย์สาธารณะ RSA ค่าเหล่านี้ทำอะไรได้บ้าง? ในตอนแรกฉันคิดว่าการป้องกันการโจมตีช่องทางด้านข้าง แต่นั่นไม่สมเหตุสมผลสำหรับรหัสสาธารณะ


พบข้อมูลเพิ่มเติมเล็กน้อยในซอร์สโค้ด:

/* มอนต์โกเมอรี่ c[] += a * b[] / R % mod */
โมฆะคงที่ montMulAdd (const RSAPublicKey * คีย์
                       uint32_t* ค
                       const uint32_t ก,
                       const uint32_t* ข) {
    uint64_t A = (uint64_t)a * b[0] + c[0];
    uint32_t d0 = (uint32_t)A * คีย์->n0inv; // <--- ที่นี่
    uint64_t B = (uint64_t)d0 * คีย์->n[0] + (uint32_t)A;
    int ฉัน;


    สำหรับ (i = 1; i <key->len; ++i) {
        A = (A >> 32) + (uint64_t)a * b[i] + c[i];
        B = (B >> 32) + (uint64_t)d0 * คีย์->n[i] + (uint32_t)A;
        ค[i - 1] = (uint32_t)ข;
    }


    ก = (ก >> 32) + (ข >> 32);


    ค[i - 1] = (uint32_t)ก;


    ถ้า (ก >> 32) {
        subM(คีย์, c);
    }
}

และ

/* การยกกำลังสาธารณะในสถานที่
** อินพุตและเอาต์พุตอาร์เรย์ไบต์แบบ big-endian ใน inout
*/
โมฆะคงที่ modpow3 (const RSAPublicKey * คีย์
                    uint8_t* ขาเข้า) {
    uint32_t a[RSANUMWORDS];
    uint32_t aR[RSANUMWORDS];
    uint32_t aaR[RSANUMWORDS];
    uint32_t *aaa = aR; /* ใช้ตำแหน่งซ้ำ */
    int ฉัน;


    /* แปลงจากอาร์เรย์ไบต์ endian ขนาดใหญ่เป็นอาร์เรย์เวิร์ด endian ขนาดเล็ก */
    สำหรับ (i = 0; i <key->len; ++i) {
        uint32_t tmp =
            (inout[((คีย์->เลน - 1 - i) * 4) + 0] << 24) |
            (inout[((คีย์->เลน - 1 - i) * 4) + 1] << 16) |
            (inout[((คีย์->เลน - 1 - i) * 4) + 2] << 8) |
            (inout[((คีย์->เลน - 1 - i) * 4) + 3] << 0);
        ก[i] = tmp;
    }


    montMul(คีย์, aR, a, คีย์->rr); /* aR = a * RR / R mod M */ // <-- ที่นี่
    montMul (คีย์, aaR, aR, aR); /* aaR = aR * aR / R ม็อด M */
    montMul (คีย์ aaa, aaR, a); /* aaa = aaR * a / R ม็อด M */


    /* ตรวจสอบให้แน่ใจว่า aaa < mod; aaa สูงสุด 1x mod ใหญ่เกินไป */
    ถ้า (geM (คีย์ aaa)) {
        subM(คีย์ aaa);
    }


    /* แปลงเป็นอาร์เรย์ไบต์ bigendian */
    สำหรับ (i = คีย์->เลน - 1; ผม >= 0; --i) {
        uint32_t tmp = aaa[i];
        *inout++ = tmp >> 24;
        *inout++ = tmp >> 16;
        *inout++ = tmp >> 8;
        *inout++ = tmp >> 0;
    }
}

ดังนั้นฉันจึงเข้าใจว่าทั้งคู่ใช้เพื่อเร่งการยกกำลังแบบแยกส่วนเมื่อใช้เลขชี้กำลังสาธารณะ 3 ถ้าเป็นเช่นนั้น ใครสามารถระบุอัลกอริทึมที่ใช้ได้บ้าง

Maarten Bodewes avatar
in flag
โอเค ฉันไปเจอโพสต์เก่าของ Thomas Pornin หมีผู้เป็นมิตรของเรา [ใน SO](https://stackoverflow.com/a/5377967/589259) ดังนั้นฉันเดาว่า `R^2` เร่งความเร็ว `กำลังสองและคูณ` เพื่อใช้การยกกำลังแบบแยกส่วน และการผกผันของ `n[0]` ช่วยเพิ่มความเร็วในการบวกโมดูลาร์มอนต์โกเมอรี่ (ใช้สำหรับการคูณ) ภายใน? หมายความว่า R^2 เป็นซิกเนเจอร์กำลังสอง mod N หรือไม่?
Score:2
ธง pe

ความเป็นไปได้ที่ง่ายที่สุดคือรวมค่าเหล่านี้ไว้เพื่อทำให้การนำไปใช้งานง่ายที่สุด กล่าวคือ สิ่งดั้งเดิมเพียงอย่างเดียวที่จำเป็นสำหรับการยกกำลังคือการคูณมอนต์โกเมอรี่

กลไกหลักของการคูณแบบมอนต์โกเมอรีคือการลดลงแบบโมดูลาร์ ซึ่งประกอบด้วยวิธีการหารของเฮนเซลโดยหลักแล้วจะสงวนไว้เฉพาะส่วนที่เหลือเท่านั้น หากคุณมีโมดูลัสคี่ $n < 2^b$และค่าบางอย่าง $x < n^2$, การคำนวณการลดมอนต์โกเมอรี่ $$ \frac{x + n\left(xn' \bmod 2^b\right)}{2^b}\,, $$ กับ $n' = -n^{-1} \bmod 2^b$ (การใช้งานด้านบนใช้ค่าที่ตัดทอน $n' = -n^{-1} \bmod 2^{32}$ซึ่งเพียงพอสำหรับการใช้งานกำลังสองอย่างง่าย) สิ่งนี้ทำให้มั่นใจได้ว่า a) ผลลัพธ์คือ $x2^{-b} \bmod n$, b) การแบ่งตาม $2^b$ เป็นเรื่องเล็กน้อยเนื่องจาก $x + n\left(xn' \bmod 2^b\right)$ เป็นทวีคูณของ $2^b$ จากการออกแบบ และ c) ผลที่ได้คือลดขนาดลงจนสุด $2n$.

เมื่อประกอบโมดูโลการดำเนินการหลายรายการ $n$เช่น ในการยกกำลัง จะสะดวกที่จะใส่ตัวถูกดำเนินการลงใน "รูปแบบมอนต์โกเมอรี่" นั่นคือ $x \mapsto x2^b \bmod n$. นี่เป็นเพราะการคูณมอนต์โกเมอรีจะคูณตัวถูกดำเนินการและลดจำนวนโดยใช้เคล็ดลับข้างต้น ดังนั้น, $$ \text{MontMul}(x2^b, y2^b) = \frac{x2^b\cdot y2^b}{2^b} \bmod n = xy2^b \bmod n\,, $$ จึงรักษารูปแบบมอนต์โกเมอรี่ไว้สำหรับการดำเนินการครั้งต่อไป

มีหลายวิธีในการแปลงอาร์กิวเมนต์เป็นแบบฟอร์มมอนต์โกเมอรี่ หนึ่งในนั้นคือการคำนวณ $x\cdot 2^b \bmod n$ ด้วยตนเองโดยใช้การหารยาว น่าเสียดายเพราะต้องใช้รหัสที่ซับซ้อนเป็นพิเศษเพื่อดำเนินการแบ่งส่วนดังกล่าว อีกทางเลือกหนึ่งคือใช้การคูณของมอนต์โกเมอรี่ในการคำนวณ $$ \text{MontMul}(x, 2^{2b}) = \frac{x\cdot 2^{2b}}{2^b} \bmod n = x2^b \bmod n\, $$ อย่างไรก็ตาม สิ่งนี้ต้องการการคำนวณล่วงหน้า $2^{2b} \bmod n$ ที่ไหนสักแห่ง ซึ่งเป็นสิ่งที่รูปแบบคีย์สาธารณะด้านบนทำทุกประการ

ในการแปลงค่า $x2^b \bmod n$ กลับคืนสู่ร่างปกติก็พอทวีคูณขึ้น $1$ โดยใช้การคูณมอนต์โกเมอรี่ หรืออีกทางหนึ่ง คูณ $x^22^b$ โดย $x$ ที่จะได้รับ $\frac{x^32^b}{2^b} \bmod n = x^3 \bmod n$.

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา