Điểm:2

Việc sử dụng lưu trữ R^2 bằng khóa chung là gì?

lá cờ in

Tôi nghĩ rằng tôi đã đảo ngược thành công khóa công khai RSA của Samsung đây. Tuy nhiên, khóa công khai dường như chủ yếu bao gồm mô-đun, nhưng nó cũng chứa một số nguyên 32 bit -1 / n[0] mod 2^32, tức là nghịch đảo của từ 32 bit đầu tiên của mô đun cũng như R^2 (có thể là mod n?).

Ai đó có thể giải thích tại sao các giá trị này được bao gồm trong khóa công khai RSA không? Những giá trị này có thể làm gì? Lần đầu tiên tôi nghĩ về việc có thể bảo vệ chống lại các cuộc tấn công kênh bên, nhưng điều đó không có ý nghĩa đối với khóa chung.


Tìm ra thêm một chút thông tin trong mã nguồn:

/* montgomery c[] += a * b[] / R % mod */
khoảng trống tĩnh montMulAdd(const RSAPublicKey *key,
                       uint32_t* c,
                       const uint32_t a,
                       const uint32_t* b) {
    uint64_t A = (uint64_t)a * b[0] + c[0];
    uint32_t d0 = (uint32_t)A * key->n0inv; // <--- TẠI ĐÂY
    uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A;
    int tôi;


    for (i = 1; i < key->len; ++i) {
        A = (A >> 32) + (uint64_t)a * b[i] + c[i];
        B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A;
        c[i - 1] = (uint32_t)B;
    }


    A = (A >> 32) + (B >> 32);


    c[i - 1] = (uint32_t)A;


    nếu (A >> 32) {
        subM(key, c);
    }
}

/* Luỹ thừa công khai tại chỗ.
** Nhập và xuất mảng byte big-endian trong inout.
*/
khoảng trống tĩnh modpow3(const RSAPublicKey *key,
                    uint8_t* đầu vào) {
    uint32_t a[RSANUMWORDS];
    uint32_t aR[RSANUMWORDS];
    uint32_t aaR[RSANUMWORDS];
    uint32_t *aaa = aR; /* Sử dụng lại vị trí. */
    int tôi;


    /* Chuyển đổi từ mảng byte cuối lớn sang mảng từ cuối nhỏ. */
    for (i = 0; i < key->len; ++i) {
        uint32_t tmp =
            (inout[((key->len - 1 - i) * 4) + 0] << 24) |
            (inout[((key->len - 1 - i) * 4) + 1] << 16) |
            (inout[((key->len - 1 - i) * 4) + 2] << 8) |
            (inout[((key->len - 1 - i) * 4) + 3] << 0);
        a[i] = tmp;
    }


    montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ // <-- TẠI ĐÂY
    montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
    montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */


    /* Đảm bảo aaa < mod; aaa nhiều nhất là 1x mod quá lớn. */
    if (geM(key, aaa)) {
        subM(key, aaa);
    }


    /*Chuyển sang mảng byte bigendian*/
    for (i = key->len - 1; i >= 0; --i) {
        uint32_t tmp = aaa[i];
        *inout++ = tmp >> 24;
        *inout++ = tmp >> 16;
        *inout++ = tmp >> 8;
        *inout++ = tmp >> 0;
    }
}

Vì vậy, tôi cho rằng cả hai đều được sử dụng để tăng tốc độ lũy thừa mô-đun khi sử dụng số mũ công khai 3? Nếu vậy, ai đó có thể chỉ ra (các) thuật toán được sử dụng không?

Maarten Bodewes avatar
lá cờ in
OK, vì vậy tôi đã tìm thấy một bài đăng cũ của Thomas Pornin, chú gấu thân thiện của chúng tôi [trên SO](https://stackoverflow.com/a/5377967/589259). Vì vậy, tôi đoán rằng `R^2` tăng tốc `bình phương và nhân lên` để thực hiện phép lũy thừa mô-đun và nghịch đảo của `n[0]` giúp tăng tốc phép cộng mô-đun Montgomery (được sử dụng để nhân) trong? Điều đó có nghĩa là R^2 là mod bình phương chữ ký N?
Điểm:2
lá cờ pe

Khả năng đơn giản nhất là những giá trị đó được đưa vào để làm cho việc triển khai trở nên đơn giản nhất có thể. Cụ thể, nguyên hàm duy nhất cần thiết cho phép lũy thừa là phép nhân Montgomery.

Cơ chế cốt lõi của phép nhân Montgomery là phép rút gọn theo mô đun, về cơ bản bao gồm phương pháp chia của Hensel chỉ bảo toàn phần còn lại. Nếu bạn có một mô đun lẻ $n < 2^b$, và một số giá trị $x < n^2$, phép tính giảm Montgomery $$ \frac{x + n\left(xn' \bmod 2^b\right)}{2^b}\,, $$ với $n' = -n^{-1} \bmod 2^b$ (việc triển khai ở trên sử dụng giá trị cắt ngắn $n' = -n^{-1} \bmod 2^{32}$, đủ để triển khai bậc hai đơn giản.). Điều này đảm bảo rằng a) kết quả là $x2^{-b} \bmod n$, b) phép chia cho $2^b$ là tầm thường, kể từ khi $x + n\left(xn' \bmod 2^b\right)$ là bội số của $2^b$ theo thiết kế, và c) kết quả được giảm kích thước tối đa $2n$.

Khi soạn thảo một số hoạt động modulo $n$, chẳng hạn như trong một phép lũy thừa, sẽ thuận tiện khi đặt các toán hạng thành "dạng Montgomery", nghĩa là $x \mapsto x2^b \bmod n$. Điều này là do phép nhân Montgomery sẽ nhân các toán hạng và rút gọn chúng bằng thủ thuật trên. Cho nên, $$ \text{MontMul}(x2^b, y2^b) = \frac{x2^b\cdot y2^b}{2^b} \bmod n = xy2^b \bmod n\,, $$ do đó giữ nguyên dạng Montgomery cho hoạt động tiếp theo.

Có một số cách để chuyển đối số sang dạng Montgomery. Một trong số đó là tính toán $x\cdot 2^b \bmod n$ thủ công, sử dụng phép chia dài. Điều này thật đáng tiếc, bởi vì nó sẽ yêu cầu mã phức tạp hơn để thực hiện phép chia nói trên. Cách khác là sử dụng phép nhân Montgomery để tính toán $$ \text{MontMul}(x, 2^{2b}) = \frac{x\cdot 2^{2b}}{2^b} \bmod n = x2^b \bmod n\,. $$ Tuy nhiên, điều này đòi hỏi phải tính toán trước $2^{2b} \bmod n$ ở đâu đó, đó chính xác là định dạng khóa công khai ở trên.

Để chuyển đổi một giá trị $x2^b \bmod n$ trở lại dạng bình thường, nó đủ để nhân nó với $1$ sử dụng phép nhân Montgomery. Hoặc, cách khác, như cách triển khai này, hãy nhân lên $x^22^b$ qua $x$ để có được $\frac{x^32^b}{2^b} \bmod n = x^3 \bmod n$.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.