ฉันคิดว่าฉันได้ทำวิศวกรรมย้อนกลับคีย์สาธารณะของ 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 ถ้าเป็นเช่นนั้น ใครสามารถระบุอัลกอริทึมที่ใช้ได้บ้าง