Score:1

วิธีพิสูจน์การถอดรหัสที่ถูกต้องใน ElGamal Cryptosystem

ธง br

ฉันกำลังทำงานในโครงการที่ใช้การเข้ารหัส ElGamal โดยใช้สัญกรณ์การคูณ โครงการนี้เป็นการดำเนินการลงคะแนนทางอินเทอร์เน็ตที่ใช้ระบบเข้ารหัสเพื่อเข้ารหัสบัตรลงคะแนนที่ได้รับ เข้ารหัสใหม่และสับเปลี่ยน จากนั้นจึงถอดรหัสในที่สุด ฉันกำลังอ้างอิงโครงการในบทความนี้ (https://www.usenix.org/conference/evt-06/simple-verifiable-elections).

ฉันรู้วิธีแสดงหลักฐานความถูกต้องสำหรับการเข้ารหัสและการเข้ารหัสซ้ำในภายหลัง แต่ฉันไม่แน่ใจว่าจะทำอย่างไรสำหรับการถอดรหัส

ฟังก์ชั่นหลัก

ฟังก์ชัน async testDecryptProof () {
    // สร้างตัวอย่าง
    ตัวอย่าง const = {
        g: '578581162149404798490571324493050333821753231896276896347588934236801486075345228356031089034308080355169502516970783985992465797790164077579971312181422206518964809883668939849570386967992767051369301215310754209280449807411021102153029377771783635510279329651149063858558329423219030908013960533321414499048784570490530207084776596253913339841694321299265784157923029847261603752469185349628532689446592521898507856757944009320377006868172969323251633981722550110871375408446896988161342745052895534300357801608217690146321171241606375301572941706622980330319103629192157393821194824468143500823157190887876038021286294694041671207075207845465680928059613160518275520282872421869149103173333949258329687311303065379518852070463040315621848668909908323797263963006103095659510784649320024411908921807300979021343984882137053231099693459838679137130760178994756250748747915572916102102876710115689234104349836600282068293111526381083439422743411854769767922191654138690358405340374558063855405817 898848980774741636240733553597229888674227126306560767485612428694999914792050501101312713302487481236334084764126207814284673857139915086576279907709746386734910200293561256639347096905974796093763848648123958776190861142984370193373964',
        p: '677088805808970643479133732614124310412316623451218811091733045838654739392363246453577008799155078839179531842224968947275228243113309850038122844034206790202276653380214548364178679947759556696213093774565712592343240601574723204104637149412506691550790846672244951946792272265332057245338838114080139164225120755358666371656799563377820758711742540625164732489435107295380237174828977225345274146615784182060315544480619981291902484596100159217062987931193501343478984350495475702937235166238839021800138523942802532967536519581875286415594806347061067009294601218779715836970031767680879370919882661828875007748699870086971737821411346178288109455141870605199207659215196027250095379359566675689788259770429733392884433737152092042439686604640479912921568537010168396445693348455112670632809025917594376152255614259482541945870534263328423690524049145709753098095473739179196969320905245503058104512347909553056470869228505715399271424136417025630569603129329944058750767224129798692688740617 502975582916178170805288244361290828581356312322935742661288429293532378052789528032585149311919895258686737427981082058024550795015310013119653546412823602194115506883191730229098656656148675288450465794412620701805411630849845729707087',
        y: '382541894983964690600293162993526991869438173208527886500815850372727490490048311900486843636684693220001234051265912000458425655926678741851522719141293453368701940787634131131196427632614127446128495491905145044221633881520859645274995287215391978093575963895028167371694057070023147521911999684763356037257097673911792867527883096328386171907773038204485470204595657681201490660401688164906946299164190680760257500808669498582862986527118065188947831650737443443357097875097317920241765784522696708021513408487224769269973358382952580868567815159167359342442935603924778373322260032811171703657045034945915068180793534715218521799021830059817105632423337977835717430573381512994650158949119647731472744313095838197029087455544614839618193123218393274500113565190237969194540716381907787190591680894096348619987465944314839217090897633240118907708728353977025942702693106124970322110442607454542840275031105740666888044262170783637186395453664958521125875844465859389112205599987204310138768154 921310117836693453278604471256064092734451809018012352357011096070124567848586327900704665937932950816991331801099649890210617795966726051925732113487988689469786194024598695027099070158275365734245304820270230893796520258396313809218890',
        x: '616914029784684855584714763340231492426100908655598976178651791609234807056421053678974092428484049715977123677899097157098622080979041003927320362108200586714799090933761996208900770559381734321267815567110342197287576060025703739925849141675379598311434697933729313626192885380020685335329593523683609103215285169226770018382824725553812040702257335748147376326047305998867888770159365634562244725476650780424134398942488222401859993782573792903020198868770888683341512671917249668225729306370351732926629458171105560538191103043275872688888584466859088043099329411213275826825557043830486585129455864229382917640721073590402279057985247862312161789404732832442295228432080975219571242951411904049824485202437265338712435017168333411682666572416980738892698829498421760253857943632271593969328472288492330564021179434722617280763223039329943080029254943467229417289060396673943590493918852192675127990512256579717957084720198671301881651767516973189185729965027130349998299701037240197132700980 314839484971221210667187937244266087926343180431454910347212397518641142169016005016264904729137249817095250718240286083681743398488217525519989102901338103699237904737924109523062555162939255331967791259668687674201147438796261750843089',
    };

    // สร้างคีย์การเข้ารหัสแบบสุ่ม
    คอสต์ s =
        '207967822958110442178778278109830447433503852402785414821328709330349706312359283387206955571124544392109210639606384509083067520738417890305269373324678620850457624398942613053579091229263806574714035427029619796357685651219711112936206300136236554121413686413214781615737095413615972501136982626464802727651907543106754703441441867970819395278183757983355179097731548906256832974088244956504713377024931955849691572802532244064111313910004860917884899557614954275881853133846262202050937167007131258789440000321676167668782902794234299192316157418176379233048725674797860563914779298033729896033445543648327892278530279961688960419952711651675214205857184412263089450401851071510115939315543359563890816581201118807559534493006019524452621986959292183026635598059041969421186679562738320841257692505660048481680152158187087105039570206133866131147519932162950362812031235948074911811982616011007001800625736370940681178846920490275589689820196930672465994980780481940620705475248697225767799033066 552773631904422782173583218760970539001080545554938763429864207029045564378485380363928567848534012360219680344285059829947885084536196661274257662548943187519599088821053868299335512862744163973139401071913251452241673699504961828835';

    // เข้ารหัสข้อความโดยใช้คีย์เข้ารหัส
    ข้อความ const = 'สวัสดีชาวโลก';

    Const encryptedMessage = รอข้อความเข้ารหัส (
        อินสแตนซ์.g,
        อินสแตนซ์.p,
        อินสแตนซ์.y,
        เอส
        ข้อความ
    );

    // ถอดรหัสข้อความโดยใช้คีย์ส่วนตัว
    const decryptedMessage = กำลังรอการถอดรหัสข้อความ (
        อินสแตนซ์.g,
        อินสแตนซ์.p,
        อินสแตนซ์.y,
        อินสแตนซ์.x,
        encryptedMessage.encryptedMessage
    );

    // พิมพ์ข้อความถอดรหัส
    console.log(decryptedMessage.decryptedMessage.toString());

    // สร้าง k (ค่าสุ่มที่ใช้สำหรับการพิสูจน์)
    const k = '43220558864635999807222494006405093554136996639442848428660649627494977326549252015956167625409717501939970915776182709535802255795811841327046836399953716791075540818773199703512742170065176842043927032153944806168393033131469866779988322330018851536228388860561713802546578689369312782369404533158072022744548501692039130608319382563304975887798942458480662500270130601098019593667725143545363191217753380237250222901141034824798469842903765210911711501751016567993724752635072194431838765933477128899257778248163199965068482546743089633809030714406496903098905056163654500580764875020269656176493932912483710515353176910076542778955451295400108157021394642711661713862976144244100957162627006366276729583244531511985931597022491676138391838344972170566256288153920117605198636967029462530358874662921957916055616766268817026800742622247905256869803113700016379056840167099105056417246287607616947661572611991798680157261664484229188188610661717186706292831905428745003502252008744644920 8860329043240893517321165335791019471565786995296353746166068105298686142956437669545600524122590537823201925276349186461350793613350249464595214594694635689236568081217849150982922989123384819183607112825771749599283303037622596134255625592473';

    // สร้างหลักฐาน
    หลักฐาน const = รอ createDecryptionProof (
        เค
        อินสแตนซ์.g,
        อินสแตนซ์.p,
        เอส
        encryptedMessage.encryptedMessage
    );

    // ตรวจสอบหลักฐาน
    การตรวจสอบ const = กำลังรอการยืนยันการถอดรหัส (
        อินสแตนซ์.g,
        อินสแตนซ์.p,
        อินสแตนซ์.y,
        พิสูจน์หลักฐาน.c,
        พิสูจน์หลักฐาน.r,
        encryptedMessage.encryptedMessage,
        decryptedMessage.decryptedMessage.toString()
    );
}

สร้างหลักฐาน

ฟังก์ชัน async createDecryptionProof (k, g, p, s, _encryptedMessage) {
    พยายาม {
        const parsedK = 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);

        // คำนวณค
        const c1 = parsedG.modPow (parsedK, parsedP);
        const c2 = parsedB.modPow (parsedK, parsedP);

        // เชื่อมต่อ c1 และ c2
        const c = c1.toString() + c2.toString();

        // แฮชซี
        const hashedC = รอ createHash (c);

        // แปลง c เป็นตัวเลข
        const cNum = Utils.parseBigInt (hashedC.hashedPassword);
        const cReady = cNum.mod(parsedP);

        // คำนวณ r
        const r = parsedK.subtract(cReady.multiply(parsedS));

        กลับ {
            ความสำเร็จ: จริง,
            การพิสูจน์: {
                ค: cReady.toString(),
                r: r.toString(),
            },
        };
    } จับ (ข้อผิดพลาด) {
        console.log (ข้อผิดพลาด);
        กลับ { สำเร็จ: เท็จ };
    }
}

ตรวจสอบหลักฐาน

ฟังก์ชัน async ยืนยันDecryptionProof(
    กรัม
    พี
    ใช่
    ค,
    อาร์
    _encryptedMessage,
    _decryptedMessage
) {
    พยายาม {
        const parsedG = Utils.parseBigInt(g);
        const parsedP = Utils.parseBigInt(p);
        const parsedY = Utils.parseBigInt(y);
        const parsedC = 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);

        // สืบทอด P
        const P = parsedA
            .multiply(parsedMessage.modInverse(parsedP))
            .mod(parsedP);
        console.log(`P: ${P}`);

        // สร้างแฮช
        const mod1 = parsedG.modPow (parsedR, parsedP);
        const mod2 = parsedY.modPow (parsedC, parsedP);
        const mod3 = parsedB.modPow (parsedR, parsedP);
        const mod4 = P.modPow (parsedC, parsedP);

        // คูณ mods
        const hash1 = mod1.multiply(mod2).mod(parsedP);
        const hash2 = mod3.multiply(mod4).mod(parsedP);

        // เชื่อมต่อ mods
        แฮช const = hash1.toString() + hash2.toString();

        // แฮช mods ที่ต่อกัน
        const hashedProof = รอ createHash (แฮช);

        // แปลงหลักฐานการแฮชเป็นตัวเลข
        หลักฐาน const = Utils.parseBigInt (hashedProof.hashedPassword);
        const proofReady = proof.mod (parsedP);

        // บันทึกค่า
        console.log(`หลักฐาน: ${proofReady}`);
        console.log(`c: ${parsedC}`);
    } จับ (ข้อผิดพลาด) {
        console.log (ข้อผิดพลาด);
        กลับ { สำเร็จ: เท็จ };
    }
}

GitHub Repo: https://github.com/Andrei-Florian/cryptosystem-public

kelalaka avatar
in flag
ส่งข้อความก่อนเข้ารหัส จากนั้นทดสอบข้อผูกมัด (แฮชคอมมิทก็เพียงพอแล้ว) หลังจากถอดรหัส?
Andrei Florian avatar
br flag
ขอบคุณสำหรับการตอบกลับ @kelalaka ฉันไม่คิดว่าสิ่งนี้จะใช้ได้กับการใช้งานของฉัน เนื่องจากแอปพลิเคชันไม่สามารถเข้าถึงบัตรลงคะแนนที่ถอดรหัสโดยผู้มีสิทธิเลือกตั้ง แอปพลิเคชันนี้ออกแบบมาสำหรับการเลือกตั้งตัวแทนตามสัดส่วน (สามารถลงคะแนนให้กับผู้สมัครหลายคน) เมื่อป้อนการเลือกผู้สมัคร ผู้ลงคะแนนไม่ได้ป้อนข้อมูลผู้สมัครโดยตรง แต่เข้ารหัสข้อความเข้ารหัส (เข้ารหัสก่อนหน้านี้โดยแอป) ด้วยเหตุนี้ แอปจึงไม่มีการเลือกผู้สมัครที่เป็นข้อความธรรมดาของผู้ลงคะแนนเพื่อสร้างข้อผูกมัด จะมีวิธีอื่นในการพิสูจน์การถอดรหัสหรือไม่?
Score:2
ธง es

บัตรลงคะแนนที่เข้ารหัสซ้ำแบบสุ่มตามรูปแบบการเข้ารหัส El Gamal ที่อ้างอิงในภาคผนวกของเอกสารจะอยู่ในรูปแบบ $(X', Y')$. เราจำเป็นต้องพิสูจน์ว่าข้อความบัตรลงคะแนนที่ประกาศไว้ $M$ มีการคำนวณอย่างแท้จริงว่า $M = X'-sY'$, ที่ไหน $s$ เป็นคีย์ส่วนตัวเดียวกันกับที่เชื่อมโยงกับคีย์สาธารณะ $Z = sG$ ที่เดิมผู้มีสิทธิเลือกตั้งใช้ในการเข้ารหัสบัตรลงคะแนน

ผู้ตรวจสอบจะคำนวณก่อน $P=(X'-M)$. เราต้องพิสูจน์ให้ผู้ตรวจสอบเห็นว่า $ P \overset{?}{=} sY'$.

ในการดำเนินการนี้ เราจำเป็นต้องจัดเตรียมการพิสูจน์ความเท่าเทียมกันของลอการิทึมแบบไม่ต่อเนื่อง (DLEQ) ซึ่งแสดงให้เห็นว่าคีย์ส่วนตัวสำหรับคีย์สาธารณะ $Z$ บนจุดฐาน $G$ เป็นคีย์ส่วนตัวเดียวกันกับคีย์สาธารณะ $พี$ บนจุดฐาน $Y'$.

บทพิสูจน์ของ DLEQ $(ค,ร)$ คำนวณได้ดังนี้

ผู้พิสูจน์

  • เลือกสเกลาร์แบบสุ่มที่สม่ำเสมอ $k$

  • คำนวณ $c=H_s(kG\mathbin\|kY')$

    ที่นี่ $H_s$ หมายถึงแฮชที่ปลอดภัยในการเข้ารหัสที่สร้างค่าสเกลาร์) และ

  • $r = k - cs$.

    การดำเนินการสเกลาร์ทั้งหมดจะดัดแปลงลำดับของจุดฐาน

ตัวตรวจสอบ (c,r,G,P,Z,Y')

  • หลักฐาน DLEQ ได้รับการตรวจสอบโดยการตรวจสอบ $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{แนว}

ในการแปลงสิ่งนี้จากสัญกรณ์การบวกเป็นสัญกรณ์การคูณ เพียงแทนที่การบวก/การลบจุดด้วยการคูณ/การหาร และแทนที่การคูณจุดด้วยการยกกำลังด้วยสเกลาร์เป็นเลขชี้กำลัง

ดังนั้นในเครื่องหมายคูณ: ถ้าจำนวนเฉพาะของคุณคือ $p$ และขนาดกลุ่มตามรอบของคุณคือ $\ell$แล้วคุณคำนวณ $P=X' \cdot (M^{-1}\ mod\ p)\ mod\ p$ (ที่ไหน $M^{-1}\ mod\ p$ หมายถึงผกผันโมดูลาร์ทวีคูณ) $c=H_s(G^k\ mod\ p \mathbin\| Y'^k\ mod\ p)$, $r=k-cs\ mod\ \ell$จากนั้นตรวจสอบ $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
in flag
อย่างที่คุณเห็น ฉันได้แก้ไขคำตอบอย่างมากเพื่อให้ชัดเจนยิ่งขึ้น คุณสามารถใช้ $\overset{?}{=}$ (`\overset{?}{=}`) แทน $==$
knaccc avatar
es flag
@kelalaka ขอบคุณค่ะ
Andrei Florian avatar
br flag
สวัสดี ขอบคุณสำหรับคำตอบ ฉันมีคำถามสองสามข้อ ประการแรก ฉันไม่คุ้นเคยกับการอ่านสัญลักษณ์นี้ และฉันก็ไม่แน่ใจว่า || คืออะไร หมายถึงสัญลักษณ์นี้จะแปลเป็นรหัสได้อย่างไร ฉันสามารถใช้ SHA256 เป็นฟังก์ชันแฮชได้หรือไม่ และสุดท้าย ตรวจสอบให้แน่ใจว่า G เป็นตัวแทนของตัวสร้างกลุ่ม
knaccc avatar
es flag
@AndreiFlorian || หมายถึงการต่อกัน เช่น. หากคุณใช้ curve25519 คะแนน EC จะมีขนาด 32 ไบต์ และหากคุณเชื่อมข้อมูลเหล่านี้เข้าด้วยกันก่อนที่จะทำการแฮช คุณจะมีการแฮช 64 ไบต์ ใช่ G เป็นตัวสร้างกลุ่ม SHA256 นั้นใช้ได้ในตัวอย่างนี้ แต่ให้ดัดแปลงด้วยลำดับของจุดฐานเพื่อให้แน่ใจว่าผลลัพธ์เป็นสเกลาร์ที่ถูกต้อง อย่างไรก็ตาม ฉันจะใช้แฮชที่ไม่เสี่ยงต่อการโจมตีแบบขยายความยาวเสมอ เช่น SHA512 ที่ถูกตัดเหลือ 256 บิต
Andrei Florian avatar
br flag
ขอบคุณสำหรับสิ่งนั้น ดูเหมือนว่าฉันกำลังดิ้นรนกับการแปลงเป็นสัญกรณ์การคูณ ฉันไม่แน่ใจ 100% ว่าสัญญาณใดที่จะเปลี่ยนแปลงและเครื่องหมายใดที่จะคงเดิม ฉันพูดถูกไหมว่า: c=H((G^k)modp || (Y'^k)modp)modp, r=(k-cs)modp (เหมือนกัน), P=(X'-M)modp (เหมือนกัน), c=(([G^r]modp) * ([Z^c]modp)modp || ([Y'^r]modp) * ([P^c]modp)modp)modp? ขอขอบคุณอีกครั้งสำหรับเวลาและขออภัยสำหรับสัญกรณ์ที่ไม่ดี
knaccc avatar
es flag
@AndreiFlorian เป็น X'/M แทนที่จะเป็น X'-M เมื่อแปลงเป็นสัญกรณ์การคูณ
Andrei Florian avatar
br flag
@knaccc ฉันค่อนข้างแน่ใจว่าฉันทำอะไรผิด คุณมีเวลาเขียนหลักฐานในรูปแบบการคูณหรือไม่? ฉันพยายามเปลี่ยนสัญญาณมาสองสามชั่วโมงแล้ว แต่ก็ยังหาหลักฐานมาตรวจสอบไม่ได้ ขอบคุณมาก.
knaccc avatar
es flag
@AndreiFlorian เมื่อใช้งาน EC การดำเนินการสเกลาร์จะดัดแปลงลำดับของจุดฐาน แต่ถ้าคุณใช้การยกกำลังปกติและไม่ได้ใช้สเกลาร์ EC คุณจะไม่ทำ $mod$ ในส่วนของ $k-cs$ เมื่อคำนวณ $r$ (ไม่ใช่ในการลบ ไม่ใช่ในการคูณ) สิ่งนี้ควรแก้ไข โดยสรุป อย่าใช้ $mod$ หรือเปลี่ยนตัวดำเนินการใดๆ เมื่อคำนวณ $r = k-cs$ แต่ที่อื่น ๆ ให้ใช้ $mod p$ และแปลงการบวกเป็นการคูณ การลบเป็นการหาร และการคูณเป็นการยกกำลัง แจ้งให้เราทราบหากแก้ไขได้
Andrei Florian avatar
br flag
@knaccc ฉันลองเปลี่ยนแล้ว แต่ก็ยังใช้งานไม่ได้ ฉันสงสัยว่าจะง่ายกว่าไหมถ้าฉันจะแบ่งปันรหัสกับคุณ ฉันได้แนบมากับโพสต์ ฉันทำงานใน JavaScript รหัสที่ฉันแนบกับคำถามมี 3 วิธี (โดยบางวิธีจะจัดการการดำเนินการบางอย่าง) ฉันเพิ่มลิงก์ไปยัง GitHub repo ซึ่งฉันมีวิธีช่วยเหลือทั้งหมดรวมอยู่ด้วย ขอบคุณอีกครั้งสำหรับเวลา ฉันซาบซึ้งจริงๆ :)
knaccc avatar
es flag
@AndreiFlorian มีหลายสิ่งหลายอย่างที่ต้องแก้ไขและแก้ปัญหาที่นั่น ฉันขอแนะนำให้คุณเริ่มต้นด้วยการตรวจสอบว่าคุณสามารถหาตัวเลขสุ่มสองตัว $b$ และ $c$ คำนวณ $a = b + c$ จากนั้นตรวจสอบว่าคุณสามารถคำนวณได้สำเร็จว่า $g^a mod p == (g^b mod p * g^c mod p) mod p$ หากคุณทำได้ถึงขั้นนั้น ให้เริ่มตรวจสอบว่าส่วนประกอบย่อยของพีชคณิตด้านบนทำงานได้อย่างถูกต้อง เช่น นั่นคือ $G^k mod p == (G^r mod p * Z^c mod p) mod p$ คุณอาจมีข้อผิดพลาดในการเข้ารหัสง่ายๆ
knaccc avatar
es flag
อา ฉันคิดว่าฉันรู้ว่ามีอะไรผิดปกติ สองสิ่ง: ประการแรก ตรวจสอบให้แน่ใจว่า "การหาร" ใช้ modinverse ไม่ใช่การหารปกติ ประการที่สอง แม้ว่าการยกกำลังจะต้องเป็น $mod p$ แต่การดำเนินการสเกลาร์ก็จำเป็นต้องทำการม็อดด้วย แต่ไม่ใช่กับ $p$ ต้องดัดแปลงด้วยขนาดกลุ่ม $g$ ขนาดกลุ่มนี้จะขึ้นอยู่กับจำนวนเฉพาะที่คุณเลือก บางครั้งมันก็แค่ $p-1$ แต่อาจมีกลุ่มวัฏจักรขนาดใหญ่หลายกลุ่ม ดังนั้นจึงอาจอยู่ในรูปแบบ $(p-1)/n$ โดยที่ n เป็นปัจจัยร่วมที่คุณต้องรู้สำหรับจำนวนเฉพาะ ฉันไม่ค่อยได้ใช้งานเกินขนาด EC ดังนั้นฉันค่อนข้างสนิมเขรอะ
Andrei Florian avatar
br flag
สวัสดี ฉันค่อนข้างแน่ใจว่าฉันหารถูกต้อง (คูณด้วย mod ผกผัน) เกี่ยวกับ mods ฉันสามารถยืนยันได้ว่าขนาดกลุ่มคือ p-1 แต่ฉันไม่แน่ใจว่าจะใช้ที่ใดและจะใช้ p ที่ใด คุณสามารถรวมตำแหน่งที่ใช้ในสูตรในคำตอบได้ไหม ฉันคิดว่านี่จะช่วยแก้ปัญหาได้ ขอขอบคุณอีกครั้ง.
knaccc avatar
es flag
ฉันได้เพิ่มเข้าไปแล้ว ตรวจสอบให้แน่ใจว่าคุณมีไลบรารีผกผันตัวคูณแบบโมดูลาร์ที่เหมาะสมสำหรับทำ $M^{-1}\ mod\ p$ นอกจากนี้ เพื่อให้เกิดข้อผิดพลาดน้อยลง ฉันขอแนะนำให้คุณมีคลาสสเกลาร์และกลุ่มองค์ประกอบ พร้อมเมธอดที่จะใช้ $mod\ p$ หรือ $mod\ \ell$ ให้คุณโดยอัตโนมัติ ดังนั้นคุณจึงไม่มีโค้ดเกลื่อนกลาด $mod$ ทุกที่และเพื่อให้คุณจำแนกได้อย่างถูกต้องเสมอว่าอะไรคือองค์ประกอบกลุ่มและอะไรคือสเกลาร์
Andrei Florian avatar
br flag
ขอบคุณมาก! ฉันตรวจสอบและทำการเปลี่ยนแปลงบางอย่างและตรวจสอบออก คุณเป็นผู้ช่วยชีวิต!

โพสต์คำตอบ

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