Điểm:1

Cách chứng minh giải mã chính xác trong hệ thống mật mã ElGamal

lá cờ br

Tôi đang làm việc trên một dự án sử dụng mật mã ElGamal bằng cách sử dụng ký hiệu nhân. Dự án là một triển khai bỏ phiếu qua internet sử dụng hệ thống mật mã để mã hóa các lá phiếu đã nhận, mã hóa lại và xáo trộn chúng, sau đó cuối cùng giải mã chúng. Tôi đang dựa trên dự án trên bài báo này (https://www.usenix.org/conference/evt-06/simple-verifiable-elections).

Tôi biết cách cung cấp bằng chứng về tính đúng đắn của quá trình mã hóa và các lần mã hóa lại sau đó. Nhưng tôi không chắc làm thế nào để làm điều này để giải mã.

chức năng chính

chức năng không đồng bộ testDecryptProof() {
    // tạo thể hiện
    ví dụ const = {
        g: '578581162149404798490571324493050333821753231896276896347588934236801486075345228356031089034308080355169502516970783985992465797790164077579971312181422206518964809883668939849570386967992767051369301215310754209280449807411021102153029377771783635510279329651149063858558329423219030908013960533321414499048784570490530207084776596253913339841694321299265784157923029847261603752469185349628532689446592521898507856757944009320377006868172969323251633981722550110871375408446896988161342745052895534300357801608217690146321171241606375301572941706622980330319103629192157393821194824468143500823157190887876038021286294694041671207075207845465680928059613160518275520282872421869149103173333949258329687311303065379518852070463040315621848668909908323797263963006103095659510784649320024411908921807300979021343984882137053231099693459838679137130760178994756250748747915572916102102876710115689234104349836600282068293111526381083439422743411854769767922191654138690358405340374558063855405817 898848980774741636240733553597229888674227126306560767485612428694999914792050501101312713302487481236334084764126207814284673857139915086576279907709746386734910200293561256639347096905974796093763848648123958776190861142984370193373964',
        p: '677088805808970643479133732614124310412316623451218811091733045838654739392363246453577008799155078839179531842224968947275228243113309850038122844034206790202276653380214548364178679947759556696213093774565712592343240601574723204104637149412506691550790846672244951946792272265332057245338838114080139164225120755358666371656799563377820758711742540625164732489435107295380237174828977225345274146615784182060315544480619981291902484596100159217062987931193501343478984350495475702937235166238839021800138523942802532967536519581875286415594806347061067009294601218779715836970031767680879370919882661828875007748699870086971737821411346178288109455141870605199207659215196027250095379359566675689788259770429733392884433737152092042439686604640479912921568537010168396445693348455112670632809025917594376152255614259482541945870534263328423690524049145709753098095473739179196969320905245503058104512347909553056470869228505715399271424136417025630569603129329944058750767224129798692688740617 502975582916178170805288244361290828581356312322935742661288429293532378052789528032585149311919895258686737427981082058024550795015310013119653546412823602194115506883191730229098656656148675288450465794412620701805411630849845729707087',
        y: '382541894983964690600293162993526991869438173208527886500815850372727490490048311900486843636684693220001234051265912000458425655926678741851522719141293453368701940787634131131196427632614127446128495491905145044221633881520859645274995287215391978093575963895028167371694057070023147521911999684763356037257097673911792867527883096328386171907773038204485470204595657681201490660401688164906946299164190680760257500808669498582862986527118065188947831650737443443357097875097317920241765784522696708021513408487224769269973358382952580868567815159167359342442935603924778373322260032811171703657045034945915068180793534715218521799021830059817105632423337977835717430573381512994650158949119647731472744313095838197029087455544614839618193123218393274500113565190237969194540716381907787190591680894096348619987465944314839217090897633240118907708728353977025942702693106124970322110442607454542840275031105740666888044262170783637186395453664958521125875844465859389112205599987204310138768154 921310117836693453278604471256064092734451809018012352357011096070124567848586327900704665937932950816991331801099649890210617795966726051925732113487988689469786194024598695027099070158275365734245304820270230893796520258396313809218890',
        x: '616914029784684855584714763340231492426100908655598976178651791609234807056421053678974092428484049715977123677899097157098622080979041003927320362108200586714799090933761996208900770559381734321267815567110342197287576060025703739925849141675379598311434697933729313626192885380020685335329593523683609103215285169226770018382824725553812040702257335748147376326047305998867888770159365634562244725476650780424134398942488222401859993782573792903020198868770888683341512671917249668225729306370351732926629458171105560538191103043275872688888584466859088043099329411213275826825557043830486585129455864229382917640721073590402279057985247862312161789404732832442295228432080975219571242951411904049824485202437265338712435017168333411682666572416980738892698829498421760253857943632271593969328472288492330564021179434722617280763223039329943080029254943467229417289060396673943590493918852192675127990512256579717957084720198671301881651767516973189185729965027130349998299701037240197132700980 314839484971221210667187937244266087926343180431454910347212397518641142169016005016264904729137249817095250718240286083681743398488217525519989102901338103699237904737924109523062555162939255331967791259668687674201147438796261750843089',
    };

    // tạo khóa mã hóa ngẫu nhiên
    hằng số =
        '207967822958110442178778278109830447433503852402785414821328709330349706312359283387206955571124544392109210639606384509083067520738417890305269373324678620850457624398942613053579091229263806574714035427029619796357685651219711112936206300136236554121413686413214781615737095413615972501136982626464802727651907543106754703441441867970819395278183757983355179097731548906256832974088244956504713377024931955849691572802532244064111313910004860917884899557614954275881853133846262202050937167007131258789440000321676167668782902794234299192316157418176379233048725674797860563914779298033729896033445543648327892278530279961688960419952711651675214205857184412263089450401851071510115939315543359563890816581201118807559534493006019524452621986959292183026635598059041969421186679562738320841257692505660048481680152158187087105039570206133866131147519932162950362812031235948074911811982616011007001800625736370940681178846920490275589689820196930672465994980780481940620705475248697225767799033066 552773631904422782173583218760970539001080545554938763429864207029045564378485380363928567848534012360219680344285059829947885084536196661274257662548943187519599088821053868299335512862744163973139401071913251452241673699504961828835';

    // mã hóa tin nhắn bằng khóa mã hóa
    tin nhắn const = 'xin chào thế giới';

    const mã hóaMessage = đang chờ mã hóaMessage(
        ví dụ.g,
        ví dụ.p,
        ví dụ.y,
        S,
        thông điệp
    );

    // giải mã tin nhắn bằng khóa riêng
    const decryptedMessage = đang chờ decryptMessage(
        ví dụ.g,
        ví dụ.p,
        ví dụ.y,
        ví dụ.x,
        mã hóaMessage.encryptedMessage
    );

    // in tin nhắn đã giải mã
    console.log(decryptedMessage.decryptedMessage.toString());

    // tạo k (giá trị ngẫu nhiên được sử dụng để chứng minh)
    const k = '43220558864635999807222494006405093554136996639442848428660649627494977326549252015956167625409717501939970915776182709535802255795811841327046836399953716791075540818773199703512742170065176842043927032153944806168393033131469866779988322330018851536228388860561713802546578689369312782369404533158072022744548501692039130608319382563304975887798942458480662500270130601098019593667725143545363191217753380237250222901141034824798469842903765210911711501751016567993724752635072194431838765933477128899257778248163199965068482546743089633809030714406496903098905056163654500580764875020269656176493932912483710515353176910076542778955451295400108157021394642711661713862976144244100957162627006366276729583244531511985931597022491676138391838344972170566256288153920117605198636967029462530358874662921957916055616766268817026800742622247905256869803113700016379056840167099105056417246287607616947661572611991798680157261664484229188188610661717186706292831905428745003502252008744644920 8860329043240893517321165335791019471565786995296353746166068105298686142956437669545600524122590537823201925276349186461350793613350249464595214594694635689236568081217849150982922989123384819183607112825771749599283303037622596134255625592473';

    // tạo bằng chứng
    const bằng chứng = đang chờ tạoDecryptionProof(
        k,
        ví dụ.g,
        ví dụ.p,
        S,
        mã hóaMessage.encryptedMessage
    );

    // xác minh bằng chứng
    xác minh const = đang chờ xác minhDecryptionProof(
        ví dụ.g,
        ví dụ.p,
        ví dụ.y,
        bằng chứng.proof.c,
        bằng chứng.proof.r,
        được mã hóa.encryptedMessage,
        decryptedMessage.decryptedMessage.toString()
    );
}

tạo bằng chứng

chức năng không đồng bộ createDecryptionProof(k, g, p, s, _encryptedMessage) {
    cố gắng {
        const parseK = Utils.parseBigInt(k);
        const parsedG = Utils.parseBigInt(g);
        const parsedP = Utils.parseBigInt(p);
        const parsedS = Utils.parseBigInt(s);

        const parsedA = Utils.parseBigInt(_encryptedMessage.a);
        const parsedB = Utils.parseBigInt(_encryptedMessage.b);

        // tính c
        const c1 = parsedG.modPow(parsedK, parsedP);
        const c2 = parsedB.modPow(parsedK, parsedP);

        // nối c1 và c2
        const c = c1.toString() + c2.toString();

        // băm c
        const hashC = chờ đợi createHash(c);

        // chuyển c thành số
        const cNum = Utils.parseBigInt(hashedC.hashedPassword);
        const cReady = cNum.mod(parsedP);

        // tính r
        const r = parsedK.subtract(cReady.multiply(parsedS));

        trở lại {
            thành công: đúng,
            bằng chứng: {
                c: cReady.toString(),
                r: r.toString(),
            },
        };
    } bắt (lỗi) {
        console.log(lỗi);
        trả lại {thành công: sai};
    }
}

xác minh bằng chứng

chức năng không đồng bộ verifyDecryptionProof(
    g,
    P,
    y,
    c,
    r,
    _encryptedMessage,
    _decryptedMessage
) {
    cố gắng {
        const parsedG = Utils.parseBigInt(g);
        const parsedP = Utils.parseBigInt(p);
        const parsedY = Utils.parseBigInt(y);
        const parseC = Utils.parseBigInt(c);
        const parsedR = Utils.parseBigInt(r);

        const parsedA = Utils.parseBigInt(_encryptedMessage.a);
        const parsedB = Utils.parseBigInt(_encryptedMessage.b);
        const parsedMessage = Utils.parseBigInt(_decryptedMessage);

        // suy ra P
        const P = đã phân tích cú phápA
            .multiply(parsedMessage.modInverse(parsedP))
            .mod(parsedP);
        console.log(`P: ${P}`);

        // tạo hàm băm
        const mod1 = parsedG.modPow(parsedR, parsedP);
        const mod2 = parsedY.modPow(parsedC, parsedP);
        const mod3 = parsedB.modPow(parsedR, parsedP);
        const mod4 = P.modPow(parsedC, parsedP);

        // nhân các mod
        const hash1 = mod1.multiply(mod2).mod(parsedP);
        const hash2 = mod3.multiply(mod4).mod(parsedP);

        // nối các mod
        const hash = hash1.toString() + hash2.toString();

        // băm các mod được nối
        const hashedProof = đang chờ createHash(hash);

        // chuyển đổi bằng chứng băm thành một số
        const proof = Utils.parseBigInt(hashedProof.hashedPassword);
        const proofReady = proof.mod(parsedP);

        // ghi các giá trị
        console.log(`proof: ${proofReady}`);
        console.log(`c: ${parsedC}`);
    } bắt (lỗi) {
        console.log(lỗi);
        trả lại {thành công: sai};
    }
}

Kho lưu trữ GitHub: https://github.com/Andrei-Florian/cryptosystem-public

kelalaka avatar
lá cờ in
Cam kết tin nhắn trước khi mã hóa, sau đó kiểm tra cam kết (hash-commit là đủ) sau khi giải mã?
Andrei Florian avatar
lá cờ br
Cảm ơn @kelalaka đã phản hồi, tôi không nghĩ rằng điều này sẽ hiệu quả với việc triển khai của tôi, vì ứng dụng không có quyền truy cập vào các lá phiếu đã giải mã do cử tri bỏ phiếu. Ứng dụng này được thiết kế cho các cuộc bầu cử đại diện theo tỷ lệ (có thể bỏ phiếu cho nhiều ứng cử viên). Khi nhập lựa chọn ứng cử viên của họ, cử tri không nhập trực tiếp các ứng cử viên mà nhập bản mã được mã hóa của họ (được ứng dụng mã hóa trước đó). Do đó, ứng dụng không bao giờ có lựa chọn ứng cử viên bằng văn bản gốc của một cử tri để tạo cam kết từ đó. Sẽ có một cách khác để chứng minh việc giải mã?
Điểm:2
lá cờ es

Các lá phiếu được mã hóa lại đã xáo trộn, theo sơ đồ mã hóa El Gamal được tham chiếu trong phần phụ lục của bài báo, sẽ ở dạng $(X', Y')$. Chúng ta cần chứng minh rằng thông điệp lá phiếu đã công bố $M$ thực sự được tính như $M = X'-sY'$, ở đâu $s$ là cùng một khóa riêng được liên kết với khóa chung $Z = sG$ mà cử tri ban đầu sử dụng để mã hóa lá phiếu.

Người xác minh trước tiên tính toán $P=(X'-M)$. Chúng ta cần chứng minh với người xác minh rằng $ P \overset{?}{=} sY'$.

Để làm điều này, chúng tôi cần cung cấp bằng chứng Tương đương logarit rời rạc (DLEQ), chứng minh rằng khóa riêng cho khóa chung $Z$ trên điểm cơ sở $G$ là cùng một khóa riêng cho khóa chung $P$ trên điểm cơ sở $Y'$.

Bằng chứng DLEQ $(c,r)$ được tính như sau:

người tục ngữ

  • chọn một vô hướng ngẫu nhiên thống nhất $k$

  • tính toán $c=H_s(kG\mathbin\|kY')$

    Đây $H_s$ có nghĩa là hàm băm bảo mật bằng mật mã tạo ra giá trị vô hướng) và

  • $r = k - cs$.

    Tất cả các hoạt động vô hướng là sửa đổi thứ tự của điểm cơ sở.

Trình xác minh(c,r,G,P,Z,Y')

  • Bằng chứng DLEQ được xác minh bằng cách kiểm tra $c\overset{?}{=}H_s(rG+cZ \mathbin\| rY'+cP)$.

\begin{align} H_s(kG - csG + cZ \mathbin\| kY' - csY' + cP)\ & =H_s(kG \color{red}{- cZ + cZ} \mathbin\| kY' \color{red}{ - cP' + cP})\ & = H_s(kG \mathbin\| kY')\ & = c\ \end{align}

Để chuyển đổi điều này từ ký hiệu cộng thành ký hiệu nhân, chỉ cần thay thế phép cộng/trừ điểm bằng phép nhân/chia và thay thế phép nhân điểm bằng phép lũy thừa với số vô hướng là số mũ.

Do đó, trong ký hiệu nhân: Nếu số nguyên tố của bạn là $p$ và kích thước nhóm tuần hoàn của bạn là $\ell$, sau đó bạn tính toán $P=X' \cdot (M^{-1}\ mod\ p)\ mod\ p$ (ở đâu $M^{-1}\ mod\ p$ có nghĩa là nghịch đảo mô-đun nhân), $c=H_s(G^k\ mod\ p \mathbin\| Y'^k\ mod\ p)$, $r=k-cs\ mod\ \ell$, sau đó xác minh $c\overset{?}{=}H_s((G^r\ mod\ p) \cdot (Z^c\ mod\ p) \ mod\ p \mathbin\| (Y'^r \ mod\ p) \cdot (P^c\ mod\ p)\ mod\ p)$.

kelalaka avatar
lá cờ in
Như bạn có thể thấy, tôi đã chỉnh sửa rất nhiều câu trả lời để làm cho nó rõ ràng hơn. Bạn có thể sử dụng $\overset{?}{=}$ (`\overset{?}{=}`)thay vì $==$
knaccc avatar
lá cờ es
@kelalaka cảm ơn
Andrei Florian avatar
lá cờ br
Xin chào, cảm ơn bạn đã trả lời. Tôi có một vài câu hỏi. Đầu tiên, tôi không quen đọc ký hiệu này và tôi không chắc || biểu thị, biểu tượng này sẽ được dịch thành mã như thế nào? Tôi có thể sử dụng SHA256 làm hàm băm không? Và cuối cùng, chỉ cần đảm bảo rằng G đại diện cho trình tạo nhóm.
knaccc avatar
lá cờ es
@AndreiFlorian || có nghĩa là nối. Ví dụ. nếu bạn đang sử dụng đường cong25519, thì các điểm EC là 32 byte và nếu bạn nối chúng trước khi băm thì bạn có 64 byte được băm. Vâng, G là trình tạo nhóm. SHA256 là tốt trong ví dụ cụ thể này, nhưng sau đó sửa đổi nó theo thứ tự của điểm cơ sở để đảm bảo rằng kết quả là một đại lượng vô hướng hợp lệ. Nhân tiện, tôi sẽ luôn thận trọng và sử dụng hàm băm không dễ bị tấn công bởi các cuộc tấn công mở rộng độ dài, chẳng hạn như SHA512 bị cắt bớt thành 256 bit.
Andrei Florian avatar
lá cờ br
Cảm ơn vì điều đó, tôi dường như đang gặp khó khăn với việc chuyển đổi sang ký hiệu phép nhân, tôi không chắc chắn 100% dấu hiệu nào sẽ thay đổi và dấu hiệu nào sẽ giữ nguyên. Tôi có đúng không khi nói rằng: c=H((G^k)modp || (Y'^k)modp)modp, r=(k-cs)modp (giống nhau), P=(X'-M)modp (giống nhau), c=(([G^r]modp) * ([Z^c]modp)modp || ([Y'^r]modp) * ([P^c]modp)modp)modp? Cảm ơn bạn một lần nữa vì đã dành thời gian và xin lỗi vì ký hiệu kém.
knaccc avatar
lá cờ es
@AndreiFlorian đó là X'/M thay vì X'-M khi chuyển đổi sang ký hiệu nhân.
Andrei Florian avatar
lá cờ br
@knaccc, tôi khá chắc chắn rằng mình đang làm sai điều gì đó. Bạn có thời gian để viết bằng chứng trong ký hiệu nhân không? Tôi đã thử chuyển đổi các biển báo trong vài giờ và vẫn không thể lấy được bằng chứng để kiểm tra. Cảm ơn nhiều.
knaccc avatar
lá cờ es
@AndreiFlorian Khi thực hiện triển khai EC, các phép toán vô hướng sẽ sửa đổi thứ tự của điểm cơ sở. Nhưng nếu bạn đang sử dụng phép lũy thừa bình thường và không sử dụng số vô hướng EC, thì bạn không thực hiện $mod$ trên phần $k-cs$ khi tính $r$ (không phải trong phép trừ và không phải trong phép nhân). Điều này sẽ sửa chữa nó. Tóm lại, không sử dụng $mod$ hoặc thay đổi bất kỳ toán tử nào khi tính toán $r = k-cs$, nhưng ở mọi nơi khác hãy sử dụng $mod p$ và chuyển đổi phép cộng thành phép nhân, phép trừ thành phép chia và phép nhân thành lũy thừa. Hãy cho tôi biết nếu điều đó sửa chữa nó.
Andrei Florian avatar
lá cờ br
@knaccc, tôi đã thử thay đổi đó nhưng nó vẫn không hoạt động. Tôi tự hỏi liệu sẽ dễ dàng hơn nếu tôi chia sẻ mã với bạn. Tôi đã đính kèm nó vào bài viết. Tôi đang làm việc bằng JavaScript, mã tôi đính kèm với câu hỏi có 3 phương thức (với một số phương thức xử lý các thao tác nhất định). Tôi đã thêm một liên kết đến repo GitHub nơi tôi có tất cả các phương thức của trình trợ giúp. Cảm ơn bạn một lần nữa cho thời gian, tôi thực sự đánh giá cao nó :).
knaccc avatar
lá cờ es
@AndreiFlorian có rất nhiều việc phải làm và gỡ lỗi ở đó. Tôi khuyên bạn nên bắt đầu bằng việc kiểm tra xem bạn có thể đưa ra hai số ngẫu nhiên $b$ và $c$ hay không, tính toán $a = b + c$, sau đó kiểm tra xem bạn có thể tính toán thành công $g^a mod p == đó không (g^b mod p * g^c mod p) mod p$. Nếu bạn có thể đạt được điều đó, thì hãy bắt đầu kiểm tra xem các thành phần con của đại số ở trên có hoạt động chính xác không, ví dụ: $G^k mod p == (G^r mod p * Z^c mod p) mod p$. Bạn có thể có một lỗi mã hóa đơn giản ở đâu đó.
knaccc avatar
lá cờ es
Ah tôi nghĩ rằng tôi biết những gì sai. Hai điều: thứ nhất, đảm bảo rằng "phân chia" sử dụng modinverse chứ không phải phân chia thông thường. Thứ hai, mặc dù các lũy thừa cần phải là $mod p$, nhưng các phép toán vô hướng cũng cần được điều chỉnh, nhưng không phải với $p$. Chúng phải được điều chỉnh với kích thước nhóm là $g$. Quy mô nhóm này sẽ phụ thuộc vào số nguyên tố bạn đã chọn. Đôi khi nó chỉ là $p-1$, nhưng có thể có nhiều nhóm tuần hoàn lớn, do đó, nó có thể ở dạng $(p-1)/n$, trong đó n là đồng sáng lập mà bạn cần biết cho số nguyên tố. Tôi hiếm khi thực hiện các triển khai như vậy ngoài EC, vì vậy tôi hơi khó tính.
Andrei Florian avatar
lá cờ br
Xin chào, tôi khá chắc chắn rằng tôi đang thực hiện đúng phép chia (nhân với nghịch đảo mod). Về các mod, tôi có thể xác nhận rằng quy mô nhóm là p-1, tuy nhiên tôi không chắc nên sử dụng cái này ở đâu và sử dụng p ở đâu. Bạn có thể bao gồm nơi chúng được sử dụng trong các công thức trong câu trả lời không. Tôi nghĩ rằng điều này sẽ giải quyết vấn đề. Cám ơn bạn một lần nữa.
knaccc avatar
lá cờ es
Tôi đã thêm nó vào. Đảm bảo rằng bạn có sẵn một thư viện nghịch đảo nhân mô-đun thích hợp để thực hiện $M^{-1}\ mod\ p$. Nhân tiện, để làm cho điều này ít bị lỗi hơn, tôi khuyên bạn nên có các lớp phần tử vô hướng và nhóm, với các phương thức sẽ tự động áp dụng $mod\ p$ hoặc $mod\ \ell$ cho bạn, vì vậy bạn không có mã lộn xộn với $mod$ ở mọi nơi và để bạn luôn phân loại chính xác phần tử nhóm là gì và phần tử vô hướng là gì.
Andrei Florian avatar
lá cờ br
Cảm ơn bạn rất nhiều! Tôi đã xem qua nó và thực hiện một số thay đổi và nó đã được kiểm tra. Bạn là một vị cứu tinh!

Đă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.