snarkyjs-elgamal
Version:
This repository implements Elgmal, a partial homomorphic encryption scheme originally described by [Taher Elgamal in 1985](https://caislab.kaist.ac.kr/lecture/2010/spring/cs548/basic/B02.pdf). This implementation includes the original version of Elgamal,
116 lines • 4.13 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Field, state, State, method, PrivateKey, SmartContract, Mina, AccountUpdate, isReady, shutdown, } from 'snarkyjs';
import { Cipher, ElGamalFF } from '../elgamal.js';
const doProofs = true;
await isReady;
class SimpleZkapp extends SmartContract {
constructor() {
super(...arguments);
this.c1 = State();
this.c2 = State();
this.c3 = State();
this.result = State();
}
encrypt(m1, m2, pk) {
this.c1.set(ElGamalFF.encrypt(m1, pk));
this.c2.set(ElGamalFF.encrypt(m2, pk));
}
multiplyCipher() {
let c1 = this.c1.get();
this.c1.assertEquals(c1);
let c2 = this.c2.get();
this.c2.assertEquals(c2);
let c3 = this.c3.get();
this.c3.assertEquals(c3);
let product = c1.mul(c2);
this.c3.set(product);
}
decrypt(secretKey) {
let result = this.c3.get();
this.c3.assertEquals(result);
let plainText = ElGamalFF.decrypt(result, secretKey);
this.result.set(plainText);
}
}
__decorate([
state(Cipher),
__metadata("design:type", Object)
], SimpleZkapp.prototype, "c1", void 0);
__decorate([
state(Cipher),
__metadata("design:type", Object)
], SimpleZkapp.prototype, "c2", void 0);
__decorate([
state(Cipher),
__metadata("design:type", Object)
], SimpleZkapp.prototype, "c3", void 0);
__decorate([
state(Field),
__metadata("design:type", Object)
], SimpleZkapp.prototype, "result", void 0);
__decorate([
method,
__metadata("design:type", Function),
__metadata("design:paramtypes", [Field, Field, Field]),
__metadata("design:returntype", void 0)
], SimpleZkapp.prototype, "encrypt", null);
__decorate([
method,
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], SimpleZkapp.prototype, "multiplyCipher", null);
__decorate([
method,
__metadata("design:type", Function),
__metadata("design:paramtypes", [Field]),
__metadata("design:returntype", void 0)
], SimpleZkapp.prototype, "decrypt", null);
let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs });
Mina.setActiveInstance(Local);
// a test account that pays all the fees, and puts additional funds into the zkapp
let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0];
// the zkapp account
let zkappKey = PrivateKey.random();
let zkappAddress = zkappKey.toPublicKey();
let zkapp = new SimpleZkapp(zkappAddress);
let { pk, sk } = ElGamalFF.generateKeys();
let m1 = Field(5);
let m2 = Field(10);
await SimpleZkapp.compile();
console.log('deploy');
let tx = await Mina.transaction(sender, () => {
AccountUpdate.fundNewAccount(sender);
zkapp.deploy({ zkappKey });
});
await tx.prove();
await tx.sign([senderKey]).send();
console.log('set and encrypt');
tx = await Mina.transaction(sender, () => {
zkapp.encrypt(m1, m2, pk);
});
await tx.prove();
await tx.sign([senderKey]).send();
console.log('multiply');
tx = await Mina.transaction(sender, () => {
zkapp.multiplyCipher();
});
await tx.prove();
await tx.sign([senderKey]).send();
console.log('decrypt');
tx = await Mina.transaction(sender, () => {
zkapp.decrypt(sk);
});
await tx.prove();
await tx.sign([senderKey]).send();
zkapp.result.get().assertEquals(m1.mul(m2));
shutdown();
//# sourceMappingURL=smart_contract.js.map