Skip to content

Commit

Permalink
Added range for Twisted ElGamal decryption
Browse files Browse the repository at this point in the history
  • Loading branch information
KlausKidman committed Aug 26, 2024
1 parent 334b908 commit 58edb3a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
18 changes: 13 additions & 5 deletions examples/typescript/twisted_el_gamal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { TwistedElGamal, TwistedEd25519PrivateKey } from "@aptos-labs/ts-sdk";

const AMOUNT = BigInt(12345)
const AMOUNT = BigInt(12_345)


const example = async () => {
Expand All @@ -15,7 +15,7 @@ const example = async () => {
const privateKey = TwistedEd25519PrivateKey.generate()
console.log("=== Key pair ===");
console.log(`Private key: ${privateKey.toString()}`);
console.log(`Pablic key: ${privateKey.publicKey().toString()}\n\n`);
console.log(`Public key: ${privateKey.publicKey().toString()}\n\n`);

const twistedElGamalInstance = new TwistedElGamal(privateKey)

Expand All @@ -29,9 +29,17 @@ const example = async () => {
const decAmount1 = twistedElGamalInstance.decrypt(ciphertext)
console.log(`Decrypted amount: ${decAmount1}\n`);

console.log("Decrypting the ciphertext starting at a specified amount");
const decAmount2 = twistedElGamalInstance.decrypt(ciphertext, 1000n)
console.log(`Decrypted amount: ${decAmount2}`);
console.log("Decrypting a ciphertext using a valid range");
const decAmount2 = twistedElGamalInstance.decrypt(ciphertext, { start: 1_000n, end: 20_000n})
console.log(`Decrypted amount: ${decAmount2}\n`);

console.log("Decrypting a ciphertext using a invalid range");
try {
twistedElGamalInstance.decrypt(ciphertext, { start: 1_000n, end: 2_000n})
} catch (e) {
console.error(e);
console.log("Failed to decrypt the amount");
}
};


Expand Down
21 changes: 14 additions & 7 deletions src/core/crypto/twistedElGamal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { TwistedEd25519PrivateKey, TwistedEd25519PublicKey } from "./twistedEd25

export type RistPoint = InstanceType<typeof RistrettoPoint>

export interface DecryptionRange {
start?: bigint;
end?: bigint;
}

/**
* Twisted ElGamal encryption/decryption
* @see {@link https://drive.google.com/file/d/1wGo-pIOPOcCQA0gjngE5kmWUQ-TxktAF/view | Veiled coins with twisted ElGamal}
Expand Down Expand Up @@ -47,10 +52,10 @@ export class TwistedElGamal {
* Decrypts the amount with Twisted ElGamal
*
* @param ciphertext сiphertext points encrypted by Twisted ElGamal
* @param startAmount Start amount from which the decryption will begin
* @param decryptionRange The range of amounts to be used in decryption
*/
public decrypt(ciphertext: TwistedElGamalCiphertext, startAmount?: bigint): bigint {
return TwistedElGamal.decryptWithSK(ciphertext, this.privateKey, startAmount)
public decrypt(ciphertext: TwistedElGamalCiphertext, decryptionRange?: DecryptionRange): bigint {
return TwistedElGamal.decryptWithSK(ciphertext, this.privateKey, decryptionRange)
}

/**
Expand Down Expand Up @@ -85,30 +90,32 @@ export class TwistedElGamal {
* Decrypts the amount with Twisted ElGamal
* @param ciphertext сiphertext points encrypted by Twisted ElGamal
* @param privateKey Twisted ElGamal Ed25519 private key.
* @param startAmount Start amount from which the decryption will begin
* @param decryptionRange The range of amounts to be used in decryption
*/
static decryptWithSK(
ciphertext: TwistedElGamalCiphertext,
privateKey: TwistedEd25519PrivateKey,
startAmount?: bigint
decryptionRange?: DecryptionRange
): bigint {
const { C, D } = ciphertext
const H = RistrettoPoint.fromHex(TwistedElGamal.HASH_BASE_POINT)
const modS = mod(bytesToNumberLE(privateKey.toUint8Array()), ed25519.CURVE.n)
const sD = RistrettoPoint.fromHex(D.toRawBytes()).multiply(modS)
const mH = RistrettoPoint.fromHex(C.toRawBytes()).subtract(sD)

let amount = startAmount ?? BigInt(0)
let amount = decryptionRange?.start ?? BigInt(0)
if (amount === BigInt(0)){
if (mH.equals(RistrettoPoint.ZERO)) return BigInt(0)

amount += BigInt(1)
}

let searchablePoint = H.multiply(amount)
const endAmount = decryptionRange?.end ?? ed25519.CURVE.n

while (!mH.equals(searchablePoint)) {
if (amount >= ed25519.CURVE.n) throw new Error("Error when decrypting the amount")
if (amount >= endAmount)
throw new Error("Error when decrypting the amount: it is not possible to decrypt the amount in the specified range")

amount += BigInt(1)
searchablePoint = searchablePoint.add(H)
Expand Down

0 comments on commit 58edb3a

Please sign in to comment.