Compare commits

...

2 Commits

Author SHA1 Message Date
Bazsalanszky 07607f1154
WIP 2023-12-05 07:06:28 +01:00
Bazsalanszky 63920550d7
Added frontend 2023-12-05 02:31:41 +01:00
145 changed files with 82885 additions and 32 deletions

17
Cargo.lock generated
View File

@ -4986,6 +4986,7 @@ dependencies = [
"pallet-aura",
"pallet-balances",
"pallet-grandpa",
"pallet-reward",
"pallet-sudo",
"pallet-template",
"pallet-timestamp",
@ -5279,6 +5280,21 @@ dependencies = [
"sp-std",
]
[[package]]
name = "pallet-reward"
version = "4.0.0-dev"
dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
"pallet_zkp_verify",
"parity-scale-codec",
"scale-info",
"sp-core",
"sp-io",
"sp-runtime",
]
[[package]]
name = "pallet-session"
version = "4.0.0-dev"
@ -5410,6 +5426,7 @@ dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
"hex",
"parity-scale-codec",
"rkyv",
"scale-info",

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>Polkadot.js Integration</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="js/bundle-polkadot-util.js"></script>
<script src="js/bundle-polkadot-util-crypto.js"></script>
<script src="js/bundle-polkadot-types.js"></script>
<script src="js/bundle-polkadot-api.js"></script>
<script src="js/bundle-polkadot-extension-dapp.js"></script>
</head>
<body>
<div class="sun"></div>
<div class="container">
<h2>Sustrate ZKP Pallet</h2>
<div class="nav-buttons">
<a href="index.html" class="nav-button">Plonk Verifier</a>
<a href="groth16.html" class="nav-button active">Groth16 Verifier</a>
</div>
<input type="file" id="fileInput" accept=".json">
<input type="file" id="fileInput2" accept=".key">
<button id="submitBtn">Submit</button>
<div id="loadingIndicator" class="loading-indicator"></div>
<div id="successIndicator" class="indicator success-indicator">&#10004;</div> <!-- Checkmark -->
<div id="failureIndicator" class="indicator failure-indicator">&#10006;</div> <!-- 'X' mark -->
</div>
<script src="script2.js"></script>
</body>
</html>

BIN
frontend/img/bg.png 100755

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Polkadot.js Integration</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="js/bundle-polkadot-util.js"></script>
<script src="js/bundle-polkadot-util-crypto.js"></script>
<script src="js/bundle-polkadot-types.js"></script>
<script src="js/bundle-polkadot-api.js"></script>
<script src="js/bundle-polkadot-extension-dapp.js"></script>
</head>
<body>
<div class="container">
<h2>Sustrate ZKP Pallet</h2>
<div class="nav-buttons">
<a href="index.html" class="nav-button active">Plonk Verifier</a>
<a href="groth16.html" class="nav-button">Groth16 Verifier</a>
</div>
<div>
<input type="text" id="input1" placeholder="Verification Key">
<input type="text" id="input2" placeholder="Public Inputs">
<input type="text" id="input3" placeholder="Proof">
<button id="submitBtn">Submit</button>
</div>
<div id="loadingIndicator" class="loading-indicator"></div>
<div id="successIndicator" class="indicator success-indicator">&#10004;</div> <!-- Checkmark -->
<div id="failureIndicator" class="indicator failure-indicator">&#10006;</div> <!-- 'X' mark -->
</div>
<script src="script.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,205 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@polkadot/util'), require('@polkadot/util-crypto')) :
typeof define === 'function' && define.amd ? define(['exports', '@polkadot/util', '@polkadot/util-crypto'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.polkadotExtensionDapp = {}, global.polkadotUtil, global.polkadotUtilCrypto));
})(this, (function (exports, util, utilCrypto) { 'use strict';
const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window;
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
function documentReadyPromise(creator) {
return new Promise((resolve) => {
if (document.readyState === 'complete') {
resolve(creator());
}
else {
window.addEventListener('load', () => resolve(creator()));
}
});
}
const packageInfo = { name: '@polkadot/extension-dapp', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-extension-dapp.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-extension-dapp.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-extension-dapp.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-extension-dapp.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '0.46.6' };
const unwrapBytes = util.u8aUnwrapBytes;
const wrapBytes = util.u8aWrapBytes;
const win = window;
win.injectedWeb3 = win.injectedWeb3 || {};
exports.isWeb3Injected = web3IsInjected();
exports.web3EnablePromise = null;
function web3IsInjected() {
return Object
.values(win.injectedWeb3)
.filter(({ connect, enable }) => !!(connect || enable))
.length !== 0;
}
function throwError(method) {
throw new Error(`${method}: web3Enable(originName) needs to be called before ${method}`);
}
function mapAccounts(source, list, ss58Format) {
return list.map(({ address, genesisHash, name, type }) => ({
address: address.length === 42
? address
: utilCrypto.encodeAddress(utilCrypto.decodeAddress(address), ss58Format),
meta: { genesisHash, name, source },
type
}));
}
function filterAccounts(list, genesisHash, type) {
return list.filter((a) => (!a.type || !type || type.includes(a.type)) &&
(!a.genesisHash || !genesisHash || a.genesisHash === genesisHash));
}
function getWindowExtensions(originName) {
return Promise
.all(Object
.entries(win.injectedWeb3)
.map(([nameOrHash, { connect, enable, version }]) => Promise
.resolve()
.then(() => connect
? connect(originName)
: enable
? enable(originName).then((e) => util.objectSpread({ name: nameOrHash, version: version || 'unknown' }, e))
: Promise.reject(new Error('No connect(..) or enable(...) hook found')))
.catch(({ message }) => {
console.error(`Error initializing ${nameOrHash}: ${message}`);
})))
.then((exts) => exts.filter((e) => !!e));
}
async function filterEnable(caller, extensions) {
if (!exports.web3EnablePromise) {
return throwError(caller);
}
const sources = await exports.web3EnablePromise;
return sources.filter(({ name }) => !extensions ||
extensions.includes(name));
}
function web3Enable(originName, compatInits = []) {
if (!originName) {
throw new Error('You must pass a name for your app to the web3Enable function');
}
const initCompat = compatInits.length
? Promise.all(compatInits.map((c) => c().catch(() => false)))
: Promise.resolve([true]);
exports.web3EnablePromise = documentReadyPromise(() => initCompat.then(() => getWindowExtensions(originName)
.then((values) => values.map((e) => {
if (!e.accounts.subscribe) {
e.accounts.subscribe = (cb) => {
e.accounts
.get()
.then(cb)
.catch(console.error);
return () => {
};
};
}
return e;
}))
.catch(() => [])
.then((values) => {
const names = values.map(({ name, version }) => `${name}/${version}`);
exports.isWeb3Injected = web3IsInjected();
console.info(`web3Enable: Enabled ${values.length} extension${values.length !== 1 ? 's' : ''}: ${names.join(', ')}`);
return values;
})));
return exports.web3EnablePromise;
}
async function web3Accounts({ accountType, extensions, genesisHash, ss58Format } = {}) {
const accounts = [];
const sources = await filterEnable('web3Accounts', extensions);
const retrieved = await Promise.all(sources.map(async ({ accounts, name: source }) => {
try {
const list = await accounts.get();
return mapAccounts(source, filterAccounts(list, genesisHash, accountType), ss58Format);
}
catch {
return [];
}
}));
retrieved.forEach((result) => {
accounts.push(...result);
});
console.info(`web3Accounts: Found ${accounts.length} address${accounts.length !== 1 ? 'es' : ''}`);
return accounts;
}
async function web3AccountsSubscribe(cb, { accountType, extensions, genesisHash, ss58Format } = {}) {
const sources = await filterEnable('web3AccountsSubscribe', extensions);
const accounts = {};
const triggerUpdate = () => cb(Object
.entries(accounts)
.reduce((result, [source, list]) => {
result.push(...mapAccounts(source, filterAccounts(list, genesisHash, accountType), ss58Format));
return result;
}, []));
const unsubs = sources.map(({ accounts: { subscribe }, name: source }) => subscribe((result) => {
accounts[source] = result;
try {
const result = triggerUpdate();
if (result && util.isPromise(result)) {
result.catch(console.error);
}
}
catch (error) {
console.error(error);
}
}));
return () => {
unsubs.forEach((unsub) => {
unsub();
});
};
}
async function web3FromSource(source) {
if (!exports.web3EnablePromise) {
return throwError('web3FromSource');
}
const sources = await exports.web3EnablePromise;
const found = source && sources.find(({ name }) => name === source);
if (!found) {
throw new Error(`web3FromSource: Unable to find an injected ${source}`);
}
return found;
}
async function web3FromAddress(address) {
if (!exports.web3EnablePromise) {
return throwError('web3FromAddress');
}
const accounts = await web3Accounts();
let found;
if (address) {
const accountU8a = utilCrypto.decodeAddress(address);
found = accounts.find((account) => util.u8aEq(utilCrypto.decodeAddress(account.address), accountU8a));
}
if (!found) {
throw new Error(`web3FromAddress: Unable to find injected ${address}`);
}
return web3FromSource(found.meta.source);
}
async function web3ListRpcProviders(source) {
const { provider } = await web3FromSource(source);
if (!provider) {
console.warn(`Extension ${source} does not expose any provider`);
return null;
}
return provider.listProviders();
}
async function web3UseRpcProvider(source, key) {
const { provider } = await web3FromSource(source);
if (!provider) {
throw new Error(`Extension ${source} does not expose any provider`);
}
const meta = await provider.startProvider(key);
return { meta, provider };
}
exports.packageInfo = packageInfo;
exports.unwrapBytes = unwrapBytes;
exports.web3Accounts = web3Accounts;
exports.web3AccountsSubscribe = web3AccountsSubscribe;
exports.web3Enable = web3Enable;
exports.web3FromAddress = web3FromAddress;
exports.web3FromSource = web3FromSource;
exports.web3ListRpcProviders = web3ListRpcProviders;
exports.web3UseRpcProvider = web3UseRpcProvider;
exports.wrapBytes = wrapBytes;
}));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,553 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@polkadot/util-crypto'), require('@polkadot/util')) :
typeof define === 'function' && define.amd ? define(['exports', '@polkadot/util-crypto', '@polkadot/util'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.polkadotKeyring = {}, global.polkadotUtilCrypto, global.polkadotUtil));
})(this, (function (exports, utilCrypto, util) { 'use strict';
const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window;
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
const PKCS8_DIVIDER = new Uint8Array([161, 35, 3, 33, 0]);
const PKCS8_HEADER = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
const PUB_LENGTH = 32;
const SEC_LENGTH = 64;
const SEED_LENGTH = 32;
const SEED_OFFSET = PKCS8_HEADER.length;
function decodePair(passphrase, encrypted, _encType) {
const encType = Array.isArray(_encType) || _encType === undefined
? _encType
: [_encType];
const decrypted = utilCrypto.jsonDecryptData(encrypted, passphrase, encType);
const header = decrypted.subarray(0, PKCS8_HEADER.length);
if (!util.u8aEq(header, PKCS8_HEADER)) {
throw new Error('Invalid Pkcs8 header found in body');
}
let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH);
let divOffset = SEED_OFFSET + SEC_LENGTH;
let divider = decrypted.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
if (!util.u8aEq(divider, PKCS8_DIVIDER)) {
divOffset = SEED_OFFSET + SEED_LENGTH;
secretKey = decrypted.subarray(SEED_OFFSET, divOffset);
divider = decrypted.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
if (!util.u8aEq(divider, PKCS8_DIVIDER)) {
throw new Error('Invalid Pkcs8 divider found in body');
}
}
const pubOffset = divOffset + PKCS8_DIVIDER.length;
const publicKey = decrypted.subarray(pubOffset, pubOffset + PUB_LENGTH);
return {
publicKey,
secretKey
};
}
function encodePair({ publicKey, secretKey }, passphrase) {
if (!secretKey) {
throw new Error('Expected a valid secretKey to be passed to encode');
}
const encoded = util.u8aConcat(PKCS8_HEADER, secretKey, PKCS8_DIVIDER, publicKey);
if (!passphrase) {
return encoded;
}
const { params, password, salt } = utilCrypto.scryptEncode(passphrase);
const { encrypted, nonce } = utilCrypto.naclEncrypt(encoded, password.subarray(0, 32));
return util.u8aConcat(utilCrypto.scryptToU8a(salt, params), nonce, encrypted);
}
function pairToJson(type, { address, meta }, encoded, isEncrypted) {
return util.objectSpread(utilCrypto.jsonEncryptFormat(encoded, ['pkcs8', type], isEncrypted), {
address,
meta
});
}
const SIG_TYPE_NONE = new Uint8Array();
const TYPE_FROM_SEED = {
ecdsa: utilCrypto.secp256k1PairFromSeed,
ed25519: utilCrypto.ed25519PairFromSeed,
ethereum: utilCrypto.secp256k1PairFromSeed,
sr25519: utilCrypto.sr25519PairFromSeed
};
const TYPE_PREFIX = {
ecdsa: new Uint8Array([2]),
ed25519: new Uint8Array([0]),
ethereum: new Uint8Array([2]),
sr25519: new Uint8Array([1])
};
const TYPE_SIGNATURE = {
ecdsa: (m, p) => utilCrypto.secp256k1Sign(m, p, 'blake2'),
ed25519: utilCrypto.ed25519Sign,
ethereum: (m, p) => utilCrypto.secp256k1Sign(m, p, 'keccak'),
sr25519: utilCrypto.sr25519Sign
};
const TYPE_ADDRESS = {
ecdsa: (p) => p.length > 32 ? utilCrypto.blake2AsU8a(p) : p,
ed25519: (p) => p,
ethereum: (p) => p.length === 20 ? p : utilCrypto.keccakAsU8a(utilCrypto.secp256k1Expand(p)),
sr25519: (p) => p
};
function isLocked(secretKey) {
return !secretKey || util.u8aEmpty(secretKey);
}
function vrfHash(proof, context, extra) {
return utilCrypto.blake2AsU8a(util.u8aConcat(context || '', extra || '', proof));
}
function createPair({ toSS58, type }, { publicKey, secretKey }, meta = {}, encoded = null, encTypes) {
const decodePkcs8 = (passphrase, userEncoded) => {
const decoded = decodePair(passphrase, userEncoded || encoded, encTypes);
if (decoded.secretKey.length === 64) {
publicKey = decoded.publicKey;
secretKey = decoded.secretKey;
}
else {
const pair = TYPE_FROM_SEED[type](decoded.secretKey);
publicKey = pair.publicKey;
secretKey = pair.secretKey;
}
};
const recode = (passphrase) => {
isLocked(secretKey) && encoded && decodePkcs8(passphrase, encoded);
encoded = encodePair({ publicKey, secretKey }, passphrase);
encTypes = undefined;
return encoded;
};
const encodeAddress = () => {
const raw = TYPE_ADDRESS[type](publicKey);
return type === 'ethereum'
? utilCrypto.ethereumEncode(raw)
: toSS58(raw);
};
return {
get address() {
return encodeAddress();
},
get addressRaw() {
const raw = TYPE_ADDRESS[type](publicKey);
return type === 'ethereum'
? raw.slice(-20)
: raw;
},
get isLocked() {
return isLocked(secretKey);
},
get meta() {
return meta;
},
get publicKey() {
return publicKey;
},
get type() {
return type;
},
decodePkcs8,
derive: (suri, meta) => {
if (type === 'ethereum') {
throw new Error('Unable to derive on this keypair');
}
else if (isLocked(secretKey)) {
throw new Error('Cannot derive on a locked keypair');
}
const { path } = utilCrypto.keyExtractPath(suri);
const derived = utilCrypto.keyFromPath({ publicKey, secretKey }, path, type);
return createPair({ toSS58, type }, derived, meta, null);
},
encodePkcs8: (passphrase) => {
return recode(passphrase);
},
lock: () => {
secretKey = new Uint8Array();
},
setMeta: (additional) => {
meta = util.objectSpread({}, meta, additional);
},
sign: (message, options = {}) => {
if (isLocked(secretKey)) {
throw new Error('Cannot sign with a locked key pair');
}
return util.u8aConcat(options.withType
? TYPE_PREFIX[type]
: SIG_TYPE_NONE, TYPE_SIGNATURE[type](util.u8aToU8a(message), { publicKey, secretKey }));
},
toJson: (passphrase) => {
const address = ['ecdsa', 'ethereum'].includes(type)
? publicKey.length === 20
? util.u8aToHex(publicKey)
: util.u8aToHex(utilCrypto.secp256k1Compress(publicKey))
: encodeAddress();
return pairToJson(type, { address, meta }, recode(passphrase), !!passphrase);
},
unlock: (passphrase) => {
return decodePkcs8(passphrase);
},
verify: (message, signature, signerPublic) => {
return utilCrypto.signatureVerify(message, signature, TYPE_ADDRESS[type](util.u8aToU8a(signerPublic))).isValid;
},
vrfSign: (message, context, extra) => {
if (isLocked(secretKey)) {
throw new Error('Cannot sign with a locked key pair');
}
if (type === 'sr25519') {
return utilCrypto.sr25519VrfSign(message, { secretKey }, context, extra);
}
const proof = TYPE_SIGNATURE[type](util.u8aToU8a(message), { publicKey, secretKey });
return util.u8aConcat(vrfHash(proof, context, extra), proof);
},
vrfVerify: (message, vrfResult, signerPublic, context, extra) => {
if (type === 'sr25519') {
return utilCrypto.sr25519VrfVerify(message, vrfResult, publicKey, context, extra);
}
const result = utilCrypto.signatureVerify(message, util.u8aConcat(TYPE_PREFIX[type], vrfResult.subarray(32)), TYPE_ADDRESS[type](util.u8aToU8a(signerPublic)));
return result.isValid && util.u8aEq(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra));
}
};
}
const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e';
class Pairs {
__internal__map = {};
add(pair) {
this.__internal__map[utilCrypto.decodeAddress(pair.address).toString()] = pair;
return pair;
}
all() {
return Object.values(this.__internal__map);
}
get(address) {
const pair = this.__internal__map[utilCrypto.decodeAddress(address).toString()];
if (!pair) {
throw new Error(`Unable to retrieve keypair '${util.isU8a(address) || util.isHex(address)
? util.u8aToHex(util.u8aToU8a(address))
: address}'`);
}
return pair;
}
remove(address) {
delete this.__internal__map[utilCrypto.decodeAddress(address).toString()];
}
}
const PairFromSeed = {
ecdsa: (seed) => utilCrypto.secp256k1PairFromSeed(seed),
ed25519: (seed) => utilCrypto.ed25519PairFromSeed(seed),
ethereum: (seed) => utilCrypto.secp256k1PairFromSeed(seed),
sr25519: (seed) => utilCrypto.sr25519PairFromSeed(seed)
};
function pairToPublic({ publicKey }) {
return publicKey;
}
class Keyring {
__internal__pairs;
__internal__type;
__internal__ss58;
decodeAddress = utilCrypto.decodeAddress;
constructor(options = {}) {
options.type = options.type || 'ed25519';
if (!['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined')) {
throw new Error(`Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type || 'unknown'}`);
}
this.__internal__pairs = new Pairs();
this.__internal__ss58 = options.ss58Format;
this.__internal__type = options.type;
}
get pairs() {
return this.getPairs();
}
get publicKeys() {
return this.getPublicKeys();
}
get type() {
return this.__internal__type;
}
addPair(pair) {
return this.__internal__pairs.add(pair);
}
addFromAddress(address, meta = {}, encoded = null, type = this.type, ignoreChecksum, encType) {
const publicKey = this.decodeAddress(address, ignoreChecksum);
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded, encType));
}
addFromJson(json, ignoreChecksum) {
return this.addPair(this.createFromJson(json, ignoreChecksum));
}
addFromMnemonic(mnemonic, meta = {}, type = this.type) {
return this.addFromUri(mnemonic, meta, type);
}
addFromPair(pair, meta = {}, type = this.type) {
return this.addPair(this.createFromPair(pair, meta, type));
}
addFromSeed(seed, meta = {}, type = this.type) {
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, PairFromSeed[type](seed), meta, null));
}
addFromUri(suri, meta = {}, type = this.type) {
return this.addPair(this.createFromUri(suri, meta, type));
}
createFromJson({ address, encoded, encoding: { content, type, version }, meta }, ignoreChecksum) {
if (version === '3' && content[0] !== 'pkcs8') {
throw new Error(`Unable to decode non-pkcs8 type, [${content.join(',')}] found}`);
}
const cryptoType = version === '0' || !Array.isArray(content)
? this.type
: content[1];
const encType = !Array.isArray(type)
? [type]
: type;
if (!['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(cryptoType)) {
throw new Error(`Unknown crypto type ${cryptoType}`);
}
const publicKey = util.isHex(address)
? util.hexToU8a(address)
: this.decodeAddress(address, ignoreChecksum);
const decoded = util.isHex(encoded)
? util.hexToU8a(encoded)
: utilCrypto.base64Decode(encoded);
return createPair({ toSS58: this.encodeAddress, type: cryptoType }, { publicKey, secretKey: new Uint8Array() }, meta, decoded, encType);
}
createFromPair(pair, meta = {}, type = this.type) {
return createPair({ toSS58: this.encodeAddress, type }, pair, meta, null);
}
createFromUri(_suri, meta = {}, type = this.type) {
const suri = _suri.startsWith('//')
? `${DEV_PHRASE}${_suri}`
: _suri;
const { derivePath, password, path, phrase } = utilCrypto.keyExtractSuri(suri);
let seed;
const isPhraseHex = util.isHex(phrase, 256);
if (isPhraseHex) {
seed = util.hexToU8a(phrase);
}
else {
const parts = phrase.split(' ');
if ([12, 15, 18, 21, 24].includes(parts.length)) {
seed = type === 'ethereum'
? utilCrypto.mnemonicToLegacySeed(phrase, '', false, 64)
: utilCrypto.mnemonicToMiniSecret(phrase, password);
}
else {
if (phrase.length > 32) {
throw new Error('specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes');
}
seed = util.stringToU8a(phrase.padEnd(32));
}
}
const derived = type === 'ethereum'
? isPhraseHex
? PairFromSeed[type](seed)
: utilCrypto.hdEthereum(seed, derivePath.substring(1))
: utilCrypto.keyFromPath(PairFromSeed[type](seed), path, type);
return createPair({ toSS58: this.encodeAddress, type }, derived, meta, null);
}
encodeAddress = (address, ss58Format) => {
return this.type === 'ethereum'
? utilCrypto.ethereumEncode(address)
: utilCrypto.encodeAddress(address, ss58Format ?? this.__internal__ss58);
};
getPair(address) {
return this.__internal__pairs.get(address);
}
getPairs() {
return this.__internal__pairs.all();
}
getPublicKeys() {
return this.__internal__pairs.all().map(pairToPublic);
}
removePair(address) {
this.__internal__pairs.remove(address);
}
setSS58Format(ss58) {
this.__internal__ss58 = ss58;
}
toJson(address, passphrase) {
return this.__internal__pairs.get(address).toJson(passphrase);
}
}
const packageInfo = { name: '@polkadot/keyring', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-keyring.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-keyring.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-keyring.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-keyring.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '12.6.1' };
const PAIRSSR25519 = [
{
p: '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d',
s: '0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011',
seed: 'Alice',
type: 'sr25519'
},
{
p: '0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f',
s: '0xe8da6c9d810e020f5e3c7f5af2dea314cbeaa0d72bc6421e92c0808a0c584a6046ab28e97c3ffc77fe12b5a4d37e8cd4afbfebbf2391ffc7cb07c0f38c023efd',
seed: 'Alice//stash',
type: 'sr25519'
},
{
p: '0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48',
s: '0x081ff694633e255136bdb456c20a5fc8fed21f8b964c11bb17ff534ce80ebd5941ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325',
seed: 'Bob',
type: 'sr25519'
},
{
p: '0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e',
s: '0xc006507cdfc267a21532394c49ca9b754ca71de21e15a1cdf807c7ceab6d0b6c3ed408d9d35311540dcd54931933e67cf1ea10d46f75408f82b789d9bd212fde',
seed: 'Bob//stash',
type: 'sr25519'
},
{
p: '0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22',
s: '0xa8f2d83016052e5d6d77b2f6fd5d59418922a09024cda701b3c34369ec43a7668faf12ff39cd4e5d92bb773972f41a7a5279ebc2ed92264bed8f47d344f8f18c',
seed: 'Charlie',
type: 'sr25519'
},
{
p: '0x306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20',
s: '0x20e05482ca4677e0edbc58ae9a3a59f6ed3b1a9484ba17e64d6fe8688b2b7b5d108c4487b9323b98b11fe36cb301b084e920f7b7895536809a6d62a451b25568',
seed: 'Dave',
type: 'sr25519'
},
{
p: '0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e',
s: '0x683576abfd5dc35273e4264c23095a1bf21c14517bece57c7f0cc5c0ed4ce06a3dbf386b7828f348abe15d76973a72009e6ef86a5c91db2990cb36bb657c6587',
seed: 'Eve',
type: 'sr25519'
},
{
p: '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c',
s: '0xb835c20f450079cf4f513900ae9faf8df06ad86c681884122c752a4b2bf74d4303e4f21bc6cc62bb4eeed5a9cce642c25e2d2ac1464093b50f6196d78e3a7426',
seed: 'Ferdie',
type: 'sr25519'
}
];
const PAIRSETHEREUM = [
{
name: 'Alith',
p: '0x02509540919faacf9ab52146c9aa40db68172d83777250b28e4679176e49ccdd9f',
s: '0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133',
type: 'ethereum'
},
{
name: 'Baltathar',
p: '0x033bc19e36ff1673910575b6727a974a9abd80c9a875d41ab3e2648dbfb9e4b518',
s: '0x8075991ce870b93a8870eca0c0f91913d12f47948ca0fd25b49c6fa7cdbeee8b',
type: 'ethereum'
},
{
name: 'Charleth',
p: '0x0234637bdc0e89b5d46543bcbf8edff329d2702bc995e27e9af4b1ba009a3c2a5e',
s: '0x0b6e18cafb6ed99687ec547bd28139cafdd2bffe70e6b688025de6b445aa5c5b',
type: 'ethereum'
},
{
name: 'Dorothy',
p: '0x02a00d60b2b408c2a14c5d70cdd2c205db8985ef737a7e55ad20ea32cc9e7c417c',
s: '0x39539ab1876910bbf3a223d84a29e28f1cb4e2e456503e7e91ed39b2e7223d68',
type: 'ethereum'
},
{
name: 'Ethan',
p: '0x025cdc005b752651cd3f728fb9192182acb3a9c89e19072cbd5b03f3ee1f1b3ffa',
s: '0x7dce9bc8babb68fec1409be38c8e1a52650206a7ed90ff956ae8a6d15eeaaef4',
type: 'ethereum'
},
{
name: 'Faith',
p: '0x037964b6c9d546da4646ada28a99e34acaa1d14e7aba861a9055f9bd200c8abf74',
s: '0xb9d2ea9a615f3165812e8d44de0d24da9bbd164b65c4f0573e1ce2c8dbd9c8df',
type: 'ethereum'
}
];
function createMeta(name, seed) {
if (!name && !seed) {
throw new Error('Testing pair should have either a name or a seed');
}
return {
isTesting: true,
name: name || seed?.replace('//', '_').toLowerCase()
};
}
function createTestKeyring(options = {}, isDerived = true) {
const keyring = new Keyring(options);
const pairs = options.type === 'ethereum'
? PAIRSETHEREUM
: PAIRSSR25519;
for (const { name, p, s, seed, type } of pairs) {
const meta = createMeta(name, seed);
const pair = !isDerived && !name && seed
? keyring.addFromUri(seed, meta, options.type)
: keyring.addPair(createPair({ toSS58: keyring.encodeAddress, type }, { publicKey: util.hexToU8a(p), secretKey: util.hexToU8a(s) }, meta));
pair.lock = () => {
};
}
return keyring;
}
const publicKey = new Uint8Array(32);
const address = '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM';
const meta = {
isTesting: true,
name: 'nobody'
};
const json = {
address,
encoded: '',
encoding: {
content: ['pkcs8', 'ed25519'],
type: 'none',
version: '0'
},
meta
};
const pair = {
address,
addressRaw: publicKey,
decodePkcs8: (_passphrase, _encoded) => undefined,
derive: (_suri, _meta) => pair,
encodePkcs8: (_passphrase) => new Uint8Array(0),
isLocked: true,
lock: () => {
},
meta,
publicKey,
setMeta: (_meta) => undefined,
sign: (_message) => new Uint8Array(64),
toJson: (_passphrase) => json,
type: 'ed25519',
unlock: (_passphrase) => undefined,
verify: (_message, _signature) => false,
vrfSign: (_message, _context, _extra) => new Uint8Array(96),
vrfVerify: (_message, _vrfResult, _context, _extra) => false
};
function nobody() {
return pair;
}
function createTestPairs(options, isDerived = true) {
const keyring = createTestKeyring(options, isDerived);
const pairs = keyring.getPairs();
const map = { nobody: nobody() };
for (const p of pairs) {
if (p.meta.name) {
map[p.meta.name] = p;
}
}
return map;
}
Object.defineProperty(exports, 'decodeAddress', {
enumerable: true,
get: function () { return utilCrypto.decodeAddress; }
});
Object.defineProperty(exports, 'encodeAddress', {
enumerable: true,
get: function () { return utilCrypto.encodeAddress; }
});
Object.defineProperty(exports, 'setSS58Format', {
enumerable: true,
get: function () { return utilCrypto.setSS58Format; }
});
exports.DEV_PHRASE = DEV_PHRASE;
exports.DEV_SEED = DEV_SEED;
exports.Keyring = Keyring;
exports.createPair = createPair;
exports.createTestKeyring = createTestKeyring;
exports.createTestPairs = createTestPairs;
exports.packageInfo = packageInfo;
}));

View File

@ -0,0 +1,150 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@polkadot/util'), require('@polkadot/util-crypto')) :
typeof define === 'function' && define.amd ? define(['exports', '@polkadot/util', '@polkadot/util-crypto'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.polkadotPhishing = {}, global.polkadotUtil, global.polkadotUtilCrypto));
})(this, (function (exports, util, utilCrypto) { 'use strict';
const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window;
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
function evaluateThis(fn) {
return fn('return this');
}
const xglobal = (typeof globalThis !== 'undefined'
? globalThis
: typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: evaluateThis(Function));
const fetch = xglobal.fetch;
async function fetchWithTimeout(url, timeout = 2000) {
const controller = new AbortController();
let isAborted = false;
const id = setTimeout(() => {
console.log(`Timeout on ${url}`);
isAborted = true;
controller.abort();
}, timeout);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(id);
return response;
}
catch (error) {
if (!isAborted) {
clearTimeout(id);
}
throw error;
}
}
function fetchJson(url, timeout) {
return fetchWithTimeout(url, timeout).then((r) => r.json());
}
const packageInfo = { name: '@polkadot/phishing', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-phishing.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-phishing.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-phishing.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-phishing.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '0.22.1' };
const PHISHING = 'https://polkadot.js.org/phishing';
const ADDRESS_JSON = `${PHISHING}/address.json`;
const CACHE_TIMEOUT = 45 * 60 * 1000;
const cacheAddr = {
end: 0,
list: {},
u8a: []
};
const cacheHost = {};
function splitHostParts(host) {
return host
.split('.')
.reverse();
}
function extractHostParts(host) {
return splitHostParts(host
.replace(/https:\/\/|http:\/\/|wss:\/\/|ws:\/\//, '')
.split('/')[0]);
}
async function retrieveAddrCache(allowCached = true) {
const now = Date.now();
if (allowCached && (now < cacheAddr.end)) {
return cacheAddr;
}
const list = await fetchJson(ADDRESS_JSON);
cacheAddr.end = now + CACHE_TIMEOUT;
cacheAddr.list = list;
cacheAddr.u8a = Object.entries(list).map(([key, addresses]) => [key, addresses.map((a) => utilCrypto.decodeAddress(a))]);
return cacheAddr;
}
async function retrieveHostCache(allowCached = true, root = '*') {
const now = Date.now();
if (allowCached && cacheHost[root] && (now < cacheHost[root].end)) {
return cacheHost[root];
}
let list;
try {
list = root === '*'
? await fetchJson(`${PHISHING}/all.json`)
: {
allow: [],
deny: await fetchJson(`${PHISHING}/all/${root}/all.json`)
};
}
catch {
list = { allow: [], deny: [] };
}
cacheHost[root] = {
end: now + CACHE_TIMEOUT,
list,
parts: list.deny.map((h) => splitHostParts(h))
};
return cacheHost[root];
}
function checkHostParts(items, hostParts) {
return items.some((parts) =>
(parts.length <= hostParts.length) &&
parts.every((part, index) => hostParts[index] === part));
}
async function retrieveAddrList(allowCached = true) {
const cache = await retrieveAddrCache(allowCached);
return cache.list;
}
async function retrieveHostList(allowCached = true, root = '*') {
const cache = await retrieveHostCache(allowCached, root);
return cache.list;
}
function checkHost(list, host) {
return checkHostParts(list.map((h) => splitHostParts(h)), extractHostParts(host));
}
async function checkAddress(address, allowCached = true) {
try {
const u8a = utilCrypto.decodeAddress(address);
const cache = await retrieveAddrCache(allowCached);
const entry = cache.u8a.find(([, u8as]) => u8as.some((a) => util.u8aEq(a, u8a)));
return entry?.[0] || null;
}
catch {
return null;
}
}
async function checkIfDenied(host, allowCached = true) {
try {
const hostParts = extractHostParts(host);
const cache = await retrieveHostCache(allowCached, hostParts[0]);
return checkHostParts(cache.parts, hostParts);
}
catch {
return false;
}
}
exports.checkAddress = checkAddress;
exports.checkHost = checkHost;
exports.checkIfDenied = checkIfDenied;
exports.packageInfo = packageInfo;
exports.retrieveAddrList = retrieveAddrList;
exports.retrieveHostList = retrieveHostList;
}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

84
frontend/script.js 100755
View File

@ -0,0 +1,84 @@
document.getElementById('submitBtn').addEventListener('click', async function () {
document.getElementById('successIndicator').style.display = 'none';
document.getElementById('failureIndicator').style.display = 'none';
document.getElementById('loadingIndicator').style.display = 'block';
// Getting values from input fields
const input1 = document.getElementById('input1').value;
const input2 = document.getElementById('input2').value;
const input3 = document.getElementById('input3').value;
// Call a specific pallet function (example: transfer)
// Replace 'palletName.methodName' with the actual pallet method you want to call
// and adjust the parameters as needed.
try {
const transaction = api.tx.zkpVerifyModule.verifyPlonk(input1, input2, input3);
const unsub = await transaction.signAndSend(selectedAccount, { signer: injector.signer }, ({ status, events, dispatchError }) => {
if (status.isInBlock || status.isFinalized) {
events.forEach(({ event: { data, method, section } }) => {
console.log(`Event: ${section}.${method}`, data.toString());
if (method === 'ValidationSuccess') {
document.getElementById('loadingIndicator').style.display = 'none';
document.getElementById('successIndicator').style.display = 'block';
}
});
if (dispatchError) {
document.getElementById('loadingIndicator').style.display = 'none';
document.getElementById('failureIndicator').style.display = 'block';
if (dispatchError.isModule) {
// For module errors, we have the section indexed, lookup
const decoded = api.registry.findMetaError(dispatchError.asModule);
const { documentation, method, section } = decoded;
console.error(`${section}.${method}: ${documentation.join(' ')}`);
} else {
// Other, CannotLookup, BadOrigin, no extra info
console.error(dispatchError.toString());
}
}
unsub();
}
});
} catch (error) {
console.error('Error:', error);
}
});
let api;
let selectedAccount;
let injector;
// On page loaded
window.addEventListener('load', async () => {
// Initialize the Polkadot.js API
const { ApiPromise, WsProvider } = polkadotApi;
const wsProvider = new WsProvider('ws://127.0.0.1:9944');
api = await ApiPromise.create({ provider: wsProvider });
// Initialize the Polkadot.js API
const { web3Accounts, web3Enable, web3FromAddress } = polkadotExtensionDapp;
// Request access to the user's Polkadot.js accounts
const extensions = await web3Enable('My Polkadot.js Integration App');
if (extensions.length === 0) {
// No extension installed, or the user refused to authorize access
return;
}
// Get the user's accounts
const allAccounts = await web3Accounts();
if (allAccounts.length === 0) {
// No accounts available
return;
}
// Select account to use (for simplicity, using the first account)
selectedAccount = allAccounts[0].address;
injector = await web3FromAddress(selectedAccount);
});
document.getElementById('successIndicator').style.display = 'none';
document.getElementById('failureIndicator').style.display = 'none';

178
frontend/script2.js 100644
View File

@ -0,0 +1,178 @@
class Proof {
constructor(a, b, c, inputs) {
this.a = a;
this.b = b;
this.c = c;
this.inputs = inputs;
}
}
class VerificationKey {
constructor(alpha, beta, gamma, delta, gammaABC) {
this.alpha = alpha;
this.beta = beta;
this.gamma = gamma;
this.delta = delta;
this.gammaABC = gammaABC;
}
}
function readFileAsJson(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function (event) {
try {
const jsonObj = JSON.parse(event.target.result);
resolve(jsonObj);
} catch (error) {
reject(error);
}
};
reader.onerror = function () {
reject(new Error("Error reading the file."));
};
reader.readAsText(file);
});
}
document.getElementById('submitBtn').addEventListener('click', async function () {
document.getElementById('successIndicator').style.display = 'none';
document.getElementById('failureIndicator').style.display = 'none';
document.getElementById('loadingIndicator').style.display = 'block';
// Getting values from input fields
const fileInput = document.getElementById('fileInput');
if (fileInput.files.length === 0) {
alert("Please upload a JSON file.");
document.getElementById('loadingIndicator').style.display = 'none';
return;
}
const file = fileInput.files[0];
let proof;
try {
const jsonObj = await readFileAsJson(file);
const a = jsonObj.proof.a;
const b = jsonObj.proof.b;
const c = jsonObj.proof.c;
const inputs = jsonObj.inputs;
proof = new Proof(a, b, c, inputs);
} catch (error) {
console.error('Error:', error);
document.getElementById('failureIndicator').style.display = 'block';
document.getElementById('loadingIndicator').style.display = 'none';
}
const fileInput2 = document.getElementById('fileInput2');
if (fileInput2.files.length === 0) {
alert("Please upload a JSON file.");
document.getElementById('loadingIndicator').style.display = 'none';
return;
}
const file2 = fileInput2.files[0];
let vk;
try {
const jsonObj = await readFileAsJson(file2);
const alpha = jsonObj.alpha;
const beta = jsonObj.beta;
const gamma = jsonObj.gamma;
const delta = jsonObj.delta;
const gammaABC = jsonObj.gamma_abc;
vk = new VerificationKey(alpha, beta, gamma, delta, gammaABC);
} catch (error) {
console.error('Error:', error);
document.getElementById('failureIndicator').style.display = 'block';
document.getElementById('loadingIndicator').style.display = 'none';
}
// Call a specific pallet function (example: transfer)
// Replace 'palletName.methodName' with the actual pallet method you want to call
// and adjust the parameters as needed.
try {
let inputs = "0x"+proof.inputs.map((input) => { return input.substring(2).toLowerCase() }).join('');
console.log(inputs);
const transaction = api.tx.zkpVerifyModule.verifyG16(vk.alpha[0], vk.alpha[1], vk.beta[0][0], vk.beta[0][1], vk.beta[1][0], vk.beta[1][1], vk.gamma[0][0], vk.gamma[0][1], vk.gamma[1][0], vk.gamma[1][1], vk.delta[0][0], vk.delta[0][1], vk.delta[1][0], vk.delta[1][1], vk.gammaABC[0][0], vk.gammaABC[0][1], vk.gammaABC[1][0], vk.gammaABC[1][1], inputs, proof.a[0], proof.a[1], proof.b[0][0], proof.b[0][1], proof.b[1][0], proof.b[1][1], proof.c[0], proof.c[1]);
const unsub = await transaction.signAndSend(selectedAccount, { signer: injector.signer }, ({ status, events, dispatchError }) => {
console.log("Hi");
if (status.isInBlock || status.isFinalized) {
events.forEach(({ event: { data, method, section } }) => {
console.log(`Event: ${section}.${method}`, data.toString());
if (method === 'ValidationSuccess') {
document.getElementById('loadingIndicator').style.display = 'none';
document.getElementById('successIndicator').style.display = 'block';
}
});
if (dispatchError) {
document.getElementById('loadingIndicator').style.display = 'none';
document.getElementById('failureIndicator').style.display = 'block';
if (dispatchError.isModule) {
// For module errors, we have the section indexed, lookup
const decoded = api.registry.findMetaError(dispatchError.asModule);
const { documentation, method, section } = decoded;
console.error(`${section}.${method}: ${documentation.join(' ')}`);
} else {
// Other, CannotLookup, BadOrigin, no extra info
console.error(dispatchError.toString());
}
}
unsub();
}
});
} catch (error) {
console.error('Error:', error);
}
});
let api;
let selectedAccount;
let injector;
// On page loaded
window.addEventListener('load', async () => {
// Initialize the Polkadot.js API
const { ApiPromise, WsProvider } = polkadotApi;
const wsProvider = new WsProvider('ws://127.0.0.1:9944');
api = await ApiPromise.create({ provider: wsProvider });
// Initialize the Polkadot.js API
const { web3Accounts, web3Enable, web3FromAddress } = polkadotExtensionDapp;
// Request access to the user's Polkadot.js accounts
const extensions = await web3Enable('My Polkadot.js Integration App');
if (extensions.length === 0) {
// No extension installed, or the user refused to authorize access
return;
}
// Get the user's accounts
const allAccounts = await web3Accounts();
if (allAccounts.length === 0) {
// No accounts available
return;
}
// Select account to use (for simplicity, using the first account)
selectedAccount = allAccounts[0].address;
injector = await web3FromAddress(selectedAccount);
});
document.getElementById('successIndicator').style.display = 'none';
document.getElementById('failureIndicator').style.display = 'none';

182
frontend/style.css 100755
View File

@ -0,0 +1,182 @@
body {
background: url('img/bg.png') no-repeat center center fixed;
background-size: cover;
font-family: 'Courier New', Courier, monospace;
color: #ffffff; /* Adjusted for better visibility against the new background */
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
overflow: hidden;
position: relative;
}
.container {
text-align: center;
padding: 20px;
border: 1px solid #ffffff; /* Adjusted color for visibility */
border-radius: 10px;
background: rgba(0, 0, 0, 0.8); /* Slightly transparent for background visibility */
z-index: 2;
position: relative;
}
input[type="text"] {
margin: 10px 0;
padding: 10px;
border: 1px solid #ffffff; /* Adjusted for visibility */
border-radius: 5px;
background-color: #000000; /* Darker background for better contrast */
color: #ffffff;
}
button {
cursor: pointer;
padding: 10px 20px;
background-color: #ff00ff; /* Neon-like color for synthwave style */
color: #ffffff;
border: none;
border-radius: 5px;
font-size: 1em;
transition: background-color 0.3s;
}
button:hover {
background-color: #ff00aa; /* Slightly different color for hover effect */
}
h2 {
color: #ffffff;
text-shadow: 0 0 10px #ff00ff; /* Neon-like glow effect */
}
.loading-indicator {
display: none;
border: 5px solid #f3f3f3; /* Light grey */
border-top: 5px solid #ff00ff; /* Synthwave style color */
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.indicator {
display: none;
font-size: 4em; /* Increased size */
line-height: 100px; /* Same as height for vertical centering */
width: 100px;
height: 100px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
margin: auto;
}
.success-indicator {
color: #00ff00; /* Green for success */
border: 2px solid #00ff00; /* Green circle */
animation: drawCheck 2s ease-in-out forwards; /* Animation for drawing */
}
.failure-indicator {
color: #ff0000; /* Red for failure */
border: 2px solid #ff0000; /* Red circle */
animation: fadeInOut 2s ease-in-out;
}
@keyframes fadeInOut {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
@keyframes drawCheck {
0% {
width: 0;
height: 0;
border-radius: 0;
opacity: 0;
}
50% {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 1;
}
100% {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 1;
}
}
input[type="file"] {
margin: 10px 0;
padding: 10px;
color: #ffffff;
background-color: #221;
border: 2px solid #ff00ff; /* Neon-like border */
border-radius: 5px;
outline: none;
text-align: center;
cursor: pointer;
transition: background-color 0.3s, transform 0.3s;
}
input[type="file"]::file-selector-button {
background-color: #ff00ff; /* Neon button color */
color: #000;
border: none;
padding: 10px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
input[type="file"]::file-selector-button:hover {
background-color: #ff00aa; /* Hover effect */
}
input[type="file"]:hover {
background-color: #332244; /* Hover effect on the input field */
transform: scale(1.05); /* Slight zoom effect on hover */
}
.nav-buttons {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.nav-button {
padding: 10px 20px;
margin: 0 10px;
background-color: #221;
color: #ffffff;
text-decoration: none;
border: 2px solid #ff00ff; /* Neon-like border */
border-radius: 5px;
transition: background-color 0.3s, transform 0.3s;
cursor: pointer;
}
.nav-button:hover {
background-color: #332244; /* Hover effect */
transform: scale(1.1); /* Slight zoom effect on hover */
}
.nav-button.active {
background-color: #ff00ff; /* Active button color */
}

View File

@ -0,0 +1,40 @@
[package]
name = "pallet-reward"
version = "4.0.0-dev"
description = "FRAME pallet template for defining custom runtime logic."
authors = ["Substrate DevHub <https://github.com/substrate-developer-hub>"]
homepage = "https://substrate.io"
edition = "2021"
license = "MIT-0"
publish = false
repository = "https://github.com/substrate-developer-hub/substrate-node-template/"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [
"derive",
] }
scale-info = { version = "2.5.0", default-features = false, features = ["derive"] }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
pallet_zkp_verify = { version = "4.0.0-dev", default-features = false, path = "../zkp_verify" }
[dev-dependencies]
sp-core = { version = "21.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
sp-io = { version = "23.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
sp-runtime = { version = "24.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
]
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"]
try-runtime = ["frame-support/try-runtime"]

View File

@ -0,0 +1 @@
License: MIT-0

View File

@ -0,0 +1,35 @@
//! Benchmarking setup for pallet-reward
#![cfg(feature = "runtime-benchmarks")]
use super::*;
#[allow(unused)]
use crate::Pallet as Template;
use frame_benchmarking::v2::*;
use frame_system::RawOrigin;
#[benchmarks]
mod benchmarks {
use super::*;
#[benchmark]
fn do_something() {
let value = 100u32.into();
let caller: T::AccountId = whitelisted_caller();
#[extrinsic_call]
do_something(RawOrigin::Signed(caller), value);
assert_eq!(Something::<T>::get(), Some(value));
}
#[benchmark]
fn cause_error() {
Something::<T>::put(100u32);
let caller: T::AccountId = whitelisted_caller();
#[extrinsic_call]
cause_error(RawOrigin::Signed(caller));
assert_eq!(Something::<T>::get(), Some(101u32));
}
impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test);
}

View File

@ -0,0 +1,139 @@
#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet::*;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod weights;
pub use weights::*;
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use pallet_zkp_verify::ZKPVerifyInterface;
#[pallet::pallet]
pub struct Pallet<T>(_);
/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
pub trait Config: frame_system::Config {
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// Type representing the weight of this pallet
type WeightInfo: WeightInfo;
///
type ZKPVerify: ZKPVerifyInterface;
}
// The pallet's runtime storage items.
// https://docs.substrate.io/main-docs/build/runtime-storage/
#[pallet::storage]
#[pallet::getter(fn something)]
// Learn more about declaring storage items:
// https://docs.substrate.io/main-docs/build/runtime-storage/#declaring-storage-items
pub type Something<T> = StorageValue<_, u32>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
RewardSuccess { who: T::AccountId },
}
#[pallet::error]
pub enum Error<T> {
RewardFailed,
}
// Dispatchable functions allows users to interact with the pallet and invoke state changes.
// These functions materialize as "extrinsics", which are often compared to transactions.
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::cause_error())]
pub fn verify_proof(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let result = T::ZKPVerify::verify_proof(
origin,
vk_alpha_1,
vk_alpha_2,
vk_beta_1_1,
vk_beta_1_2,
vk_beta_2_1,
vk_beta_2_2,
vk_gamma_1_1,
vk_gamma_1_2,
vk_gamma_2_1,
vk_gamma_2_2,
vk_delta_1_1,
vk_delta_1_2,
vk_delta_2_1,
vk_delta_2_2,
vk_gamma_abc_1_1,
vk_gamma_abc_1_2,
vk_gamma_abc_2_1,
vk_gamma_abc_2_2,
inputs,
proof_a_1,
proof_a_2,
proof_b_1_1,
proof_b_1_2,
proof_b_2_1,
proof_b_2_2,
proof_c_1,
proof_c_2,
);
if result {
Self::deposit_event(Event::RewardSuccess { who });
Ok(())
} else {
Err(Error::<T>::RewardFailed.into())
}
}
}
}

View File

@ -0,0 +1,54 @@
use crate as pallet_reward;
use frame_support::traits::{ConstU16, ConstU64};
use sp_core::H256;
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage,
};
type Block = frame_system::mocking::MockBlock<Test>;
// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
pub enum Test
{
System: frame_system,
TemplateModule: pallet_reward,
}
);
impl frame_system::Config for Test {
type BaseCallFilter = frame_support::traits::Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU64<250>;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ConstU16<42>;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}
impl pallet_reward::Config for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}
// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
frame_system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
}

View File

@ -0,0 +1,27 @@
use crate::{mock::*, Error, Event};
use frame_support::{assert_noop, assert_ok};
#[test]
fn it_works_for_default_value() {
new_test_ext().execute_with(|| {
// Go past genesis block so events get deposited
System::set_block_number(1);
// Dispatch a signed extrinsic.
assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42));
// Read pallet storage and assert an expected result.
assert_eq!(TemplateModule::something(), Some(42));
// Assert that the correct event was deposited
System::assert_last_event(Event::SomethingStored { something: 42, who: 1 }.into());
});
}
#[test]
fn correct_error_for_none_value() {
new_test_ext().execute_with(|| {
// Ensure the expected error is thrown when no value is present.
assert_noop!(
TemplateModule::cause_error(RuntimeOrigin::signed(1)),
Error::<Test>::NoneValue
);
});
}

View File

@ -0,0 +1,90 @@
//! Autogenerated weights for pallet_template
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-04-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `Alexs-MacBook-Pro-2.local`, CPU: `<UNKNOWN>`
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
// Executed Command:
// ../../target/release/node-template
// benchmark
// pallet
// --chain
// dev
// --pallet
// pallet_template
// --extrinsic
// *
// --steps=50
// --repeat=20
// --wasm-execution=compiled
// --output
// pallets/template/src/weights.rs
// --template
// ../../.maintain/frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use core::marker::PhantomData;
/// Weight functions needed for pallet_template.
pub trait WeightInfo {
fn do_something() -> Weight;
fn cause_error() -> Weight;
}
/// Weights for pallet_template using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: TemplateModule Something (r:0 w:1)
/// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
fn do_something() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 8_000_000 picoseconds.
Weight::from_parts(9_000_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: TemplateModule Something (r:1 w:1)
/// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
fn cause_error() -> Weight {
// Proof Size summary in bytes:
// Measured: `32`
// Estimated: `1489`
// Minimum execution time: 6_000_000 picoseconds.
Weight::from_parts(6_000_000, 1489)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}
// For backwards compatibility and tests
impl WeightInfo for () {
/// Storage: TemplateModule Something (r:0 w:1)
/// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
fn do_something() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 8_000_000 picoseconds.
Weight::from_parts(9_000_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: TemplateModule Something (r:1 w:1)
/// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
fn cause_error() -> Weight {
// Proof Size summary in bytes:
// Measured: `32`
// Estimated: `1489`
// Minimum execution time: 6_000_000 picoseconds.
Weight::from_parts(6_000_000, 1489)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
}

View File

@ -34,6 +34,7 @@ dusk-jubjub = { version ="0.13.1", default-features = false}
dusk-plonk = {version = "0.17.0", features = ["rkyv-impl","alloc"], default-features = false }
dusk-bls12_381 = {version = "0.12.3", features = ["rkyv-impl","pairings","alloc"], default-features = false}
rkyv = { version = "0.7.42", features = ["validation","size_32"], default-features = false }
hex = { version = "0.4.3" ,features = ["alloc"], default-features = false}

View File

@ -0,0 +1,117 @@
use core::slice::Chunks;
use ark_bls12_381::{Bls12_381, Fr};
use ark_groth16::{prepare_verifying_key, Groth16, Proof, VerifyingKey};
use ark_serialize::CanonicalDeserialize;
use ark_std::vec::Vec;
use hex;
pub struct G1AffineParts {
pub part_1: Vec<u8>,
pub part_2: Vec<u8>,
}
pub struct G2AffineParts {
pub part_1_1: Vec<u8>,
pub part_1_2: Vec<u8>,
pub part_2_1: Vec<u8>,
pub part_2_2: Vec<u8>,
}
pub struct VKParts {
pub alpha: G1AffineParts,
pub beta: G2AffineParts,
pub gamma: G2AffineParts,
pub delta: G2AffineParts,
pub gamma_abc_1: G1AffineParts,
pub gamma_abc_2: G1AffineParts,
}
pub struct ProofParts {
pub a: G1AffineParts,
pub b: G2AffineParts,
pub c: G1AffineParts,
}
fn assemble_vk(vk: &VKParts) -> VerifyingKey<Bls12_381> {
let alpha = [&vk.alpha.part_1[..], &vk.alpha.part_2[..]].concat();
let beta = [
&vk.beta.part_1_2[..],
&vk.beta.part_1_1[..],
&vk.beta.part_2_2[..],
&vk.beta.part_2_1,
]
.concat();
let gamma = [
&vk.gamma.part_1_2[..],
&vk.gamma.part_1_1[..],
&vk.gamma.part_2_2[..],
&vk.gamma.part_2_1,
]
.concat();
let delta = [
&vk.delta.part_1_2[..],
&vk.delta.part_1_1[..],
&vk.delta.part_2_2[..],
&vk.delta.part_2_1,
]
.concat();
let gamma_abc = [
&hex::decode("0200000000000000").unwrap()[..],
&vk.gamma_abc_1.part_1[..],
&vk.gamma_abc_1.part_2[..],
&vk.gamma_abc_2.part_1[..],
&vk.gamma_abc_2.part_2[..],
]
.concat();
let vk_bytes = [
&alpha[..],
&beta[..],
&gamma[..],
&delta[..],
&gamma_abc[..],
]
.concat();
return VerifyingKey::<Bls12_381>::deserialize_uncompressed(&*vk_bytes)
.expect("Failed to create deserialize verifying key");
}
fn assemble_proof(proof: &ProofParts) -> Proof<Bls12_381> {
let a = [&proof.a.part_1[..], &proof.a.part_2[..]].concat();
let b = [
&proof.b.part_1_2[..],
&proof.b.part_1_1[..],
&proof.b.part_2_2[..],
&proof.b.part_2_1,
]
.concat();
let c = [&proof.c.part_1[..], &proof.c.part_2[..]].concat();
let proof_bytes = [&a[..], &b[..], &c[..]].concat();
return Proof::<Bls12_381>::deserialize_uncompressed(&*proof_bytes)
.expect("Failed to deserialize proof");
}
fn assemble_inputs(public_inputs: &Vec<u8>) -> Vec<Fr> {
let mut frs: Vec<Fr> = Vec::new();
let chunks: Chunks<u8> = public_inputs.chunks(32);
for c in chunks {
let c_rev: Vec<u8> = c.into_iter().rev().cloned().collect();
let fr: Fr = Fr::deserialize_uncompressed(&*c_rev).expect("Failed to deserialize Fr");
frs.push(fr);
}
return frs;
}
fn verify_(vk: &VerifyingKey<Bls12_381>, proof: &Proof<Bls12_381>, public_inputs: &[Fr]) -> bool {
return Groth16::<Bls12_381>::verify_proof(&prepare_verifying_key(&vk), &proof, &public_inputs)
.expect("Error during proof verification");
}
pub fn verify(vk: &VKParts, proof: &ProofParts, public_inputs: &Vec<u8>) -> bool {
return verify_(&assemble_vk(vk), &assemble_proof(proof), &assemble_inputs(public_inputs)[..]);
}

View File

@ -17,6 +17,8 @@ mod tests;
mod benchmarking;
pub mod weights;
pub use weights::*;
mod groth16;
use crate::groth16::{G1AffineParts, G2AffineParts, ProofParts, VKParts};
#[frame_support::pallet]
pub mod pallet {
@ -77,62 +79,144 @@ pub mod pallet {
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::cause_error())]
pub fn verify_proof(origin: OriginFor<T>, vk: Vec<u8>,inputs: Vec<u8>,proof: Vec<u8>) -> DispatchResult {
pub fn verify_g16(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let cursor = Cursor::new(&vk);
let vk = <Groth16<Bls12_381> as SNARK<BlsFr>>::VerifyingKey::deserialize_with_mode(
cursor,
Compress::No,
Validate::No,
).unwrap();
let vk_parts = VKParts {
alpha: G1AffineParts {
part_1: vk_alpha_1,
part_2: vk_alpha_2,
},
beta: G2AffineParts {
part_1_1: vk_beta_1_1,
part_1_2: vk_beta_1_2,
part_2_1: vk_beta_2_1,
part_2_2: vk_beta_2_2,
},
gamma: G2AffineParts {
part_1_1: vk_gamma_1_1,
part_1_2: vk_gamma_1_2,
part_2_1: vk_gamma_2_1,
part_2_2: vk_gamma_2_2,
},
delta: G2AffineParts {
part_1_1: vk_delta_1_1,
part_1_2: vk_delta_1_2,
part_2_1: vk_delta_2_1,
part_2_2: vk_delta_2_2,
},
gamma_abc_1: G1AffineParts{
part_1: vk_gamma_abc_1_1,
part_2: vk_gamma_abc_1_2,
},
gamma_abc_2: G1AffineParts{
part_1: vk_gamma_abc_2_1,
part_2: vk_gamma_abc_2_2,
},
};
let cursor = Cursor::new(&inputs);
let inputs: ark_ff::Fp<ark_ff::MontBackend<ark_bls12_381::FrConfig, 4>, 4> =
Fp::deserialize_with_mode(cursor, Compress::No, Validate::No).unwrap();
let proof_parts = ProofParts {
a: G1AffineParts {
part_1: proof_a_1,
part_2: proof_a_2,
},
b: G2AffineParts {
part_1_1: proof_b_1_1,
part_1_2: proof_b_1_2,
part_2_1: proof_b_2_1,
part_2_2: proof_b_2_2,
},
c: G1AffineParts {
part_1: proof_c_1,
part_2: proof_c_2,
},
};
let cursor = Cursor::new(&proof);
let proof =
<Groth16<Bls12_381> as SNARK<BlsFr>>::Proof::deserialize_with_mode(
cursor,
Compress::No,
Validate::No,
).unwrap();
let result = Groth16::<Bls12_381>::verify(&vk, &[inputs], &proof).unwrap();
if(result){
// let result = Groth16::<Bls12_381>::verify(&vk, &[inputs], &proof).unwrap();
let result: bool = groth16::verify(&vk_parts, &proof_parts, &inputs);
if result {
Self::deposit_event(Event::ValidationSuccess { who });
Ok(())
}else{
} else {
Err(Error::<T>::ValidationFailed.into())
}
}
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::cause_error())]
pub fn verify_proof_plonk(origin: OriginFor<T>, vk: Vec<u8>, inputs: Vec<u8>,proof: Vec<u8>) -> DispatchResult {
pub fn verify_plonk(origin: OriginFor<T>, vk: Vec<u8>, inputs: Vec<u8>,proof: Vec<u8>) -> DispatchResult {
let who = ensure_signed(origin)?;
let result_vk = Verifier::try_from_bytes(&vk[..]);
let verifier: Verifier = Verifier::try_from_bytes(&vk[..]).expect("Failed to load verifier");
let verifier = match result_vk {
Ok(verifier) => verifier,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let archived = rkyv::check_archived_root::<Proof>(&proof[..]).unwrap();
let archived = match rkyv::check_archived_root::<Proof>(&proof[..]){
Ok(archived) => archived,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let proof: Proof = archived.deserialize(&mut rkyv::Infallible).unwrap();
let archived = rkyv::check_archived_root::<Vec<BlsScalar>>(&inputs[..]).unwrap();
let inputs: Vec<BlsScalar> = archived.deserialize(&mut rkyv::Infallible).unwrap();
let proof: Proof = match archived.deserialize(&mut rkyv::Infallible) {
Ok(proof) => proof,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let archived = match rkyv::check_archived_root::<Vec<BlsScalar>>(&inputs[..]) {
Ok(archived) => archived,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let inputs: Vec<BlsScalar> = match archived.deserialize(&mut rkyv::Infallible) {
Ok(inputs) => inputs,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let verification =verifier.verify(&proof, &inputs);
let result = verification.is_ok();
if(result){
if result {
Self::deposit_event(Event::ValidationSuccess { who });
Ok(())
}else{
@ -174,4 +258,112 @@ pub mod pallet {
}
}*/
}
}
pub trait ZKPVerifyInterface {
fn verify_g16(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DispatchResult;
}
impl<T: Config> ZKPVerifyInterface for Pallet<T> {
fn verify_g16(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DistpacthResult {
//) -> Result<DispatchResult, DispatchError> {
return Self::verify_g16(
origin,
vk_alpha_1,
vk_alpha_2,
vk_beta_1_1,
vk_beta_1_2,
vk_beta_2_1,
vk_beta_2_2,
vk_gamma_1_1,
vk_gamma_1_2,
vk_gamma_2_1,
vk_gamma_2_2,
vk_delta_1_1,
vk_delta_1_2,
vk_delta_2_1,
vk_delta_2_2,
vk_gamma_abc_1_1,
vk_gamma_abc_1_2,
vk_gamma_abc_2_1,
vk_gamma_abc_2_2,
inputs,
proof_a_1,
proof_a_2,
proof_b_1_1,
proof_b_1_2,
proof_b_2_1,
proof_b_2_2,
proof_c_1,
proof_c_2,
);
}
}
}

View File

@ -50,6 +50,7 @@ frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, g
# Local Dependencies
pallet-template = { version = "4.0.0-dev", default-features = false, path = "../pallets/template" }
pallet_zkp_verify = { version = "4.0.0-dev", default-features = false, path = "../pallets/zkp_verify" }
pallet-reward = { version = "4.0.0-dev", default-features = false, path = "../pallets/reward" }
[build-dependencies]
substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/paritytech/substrate.git", optional = true , branch = "polkadot-v1.0.0" }

View File

@ -52,6 +52,9 @@ pub use pallet_template;
/// Import the ZKP verifier pallet.
pub use pallet_zkp_verify;
/// Import the reward pallet.
pub use pallet_reward;
/// An index to a block.
pub type BlockNumber = u32;
@ -283,6 +286,12 @@ impl pallet_zkp_verify::Config for Runtime {
type WeightInfo = pallet_zkp_verify::weights::SubstrateWeight<Runtime>;
}
/// Configure the pallet-reward in pallets/reward..
impl pallet_reward::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_reward::weights::SubstrateWeight<Runtime>;
}
// Create the runtime by composing the FRAME pallets that were previously configured.
construct_runtime!(
pub struct Runtime {
@ -296,6 +305,7 @@ construct_runtime!(
// Include the custom logic from the pallet-template in the runtime.
TemplateModule: pallet_template,
ZKPVerifyModule: pallet_zkp_verify,
RewardModule: pallet_reward,
}
);
@ -345,6 +355,7 @@ mod benches {
[pallet_sudo, Sudo]
[pallet_template, TemplateModule]
[pallet_zkp_verify, ZKPVerifyModule]
[pallet_reward, RewardModule]
);
}

36
zokrates_prover/.gitignore vendored 100644
View File

@ -0,0 +1,36 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/

View File

@ -0,0 +1,37 @@
#pragma curve bn128
// Parameters are based on: https://github.com/HarryR/ethsnarks/tree/9cdf0117c2e42c691e75b98979cb29b099eca998/src/jubjub
// Note: parameters will be updated soon to be more compatible with zCash's implementation
struct BabyJubJubParams {
field JUBJUB_C;
field JUBJUB_A;
field JUBJUB_D;
field MONT_A;
field MONT_B;
field[2] INFINITY;
field Gu;
field Gv;
}
const BabyJubJubParams BABYJUBJUB_PARAMS = BabyJubJubParams {
// Order of the curve for reference: 21888242871839275222246405745257275088614511777268538073601725287587578984328
JUBJUB_C: 8, // Cofactor
JUBJUB_A: 168700, // Coefficient A
JUBJUB_D: 168696, // Coefficient D
// Montgomery parameters
MONT_A: 168698,
MONT_B: 1,
// Point at infinity
INFINITY: [0, 1],
// Generator
Gu: 16540640123574156134436876038791482806971768689494387082833631921987005038935,
Gv: 20819045374670962167435360035096875258406992893633759881276124905556507972311
};
def main() -> BabyJubJubParams {
return BABYJUBJUB_PARAMS;
}

View File

@ -0,0 +1,20 @@
from "ecc/babyjubjubParams" import BabyJubJubParams;
// Add two points on a twisted Edwards curve
// Curve parameters are defined with the last argument
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Addition_on_twisted_Edwards_curves
def main(field[2] pt1, field[2] pt2, BabyJubJubParams context) -> field[2] {
field a = context.JUBJUB_A;
field d = context.JUBJUB_D;
field u1 = pt1[0];
field v1 = pt1[1];
field u2 = pt2[0];
field v2 = pt2[1];
field uOut = (u1*v2 + v1*u2) / (1 + d*u1*u2*v1*v2);
field vOut = (v1*v2 - a*u1*u2) / (1 - d*u1*u2*v1*v2);
return [uOut, vOut];
}

View File

@ -0,0 +1,21 @@
import "utils/pack/bool/nonStrictUnpack256" as unpack256;
// Compress JubJub Curve Point to 256bit array using big endianness bit order
// Python reference code from pycrypto:
// def compress(self):
// x = self.x.n
// y = self.y.n
// return int.to_bytes(y | ((x & 1) << 255), 32, "big")
def main(field[2] pt) -> bool[256] {
field x = pt[0];
field y = pt[1];
bool[256] xBits = unpack256(x);
bool[256] mut yBits = unpack256(y);
bool sign = xBits[255];
yBits[0] = sign;
return yBits;
}

View File

@ -0,0 +1,9 @@
// Negate a point on an Edwards curve
// Curve parameters are defined with the last argument
// Twisted Edwards Curves, BBJLP-2008, section 2 pg 2
def main(field[2] pt) -> field[2] {
field u = pt[0];
field v = pt[1];
return [-u, v];
}

View File

@ -0,0 +1,17 @@
from "ecc/babyjubjubParams" import BabyJubJubParams;
// Check if a point is on a twisted Edwards curve
// Curve parameters are defined with the last argument
// See appendix 3.3.1 of Zcash protocol specification:
// https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
def main(field[2] pt, BabyJubJubParams context) -> bool {
field a = context.JUBJUB_A;
field d = context.JUBJUB_D;
field uu = pt[0] * pt[0];
field vv = pt[1] * pt[1];
field uuvv = uu * vv;
assert(a * uu + vv == 1 + d * uuvv);
return true;
}

View File

@ -0,0 +1,26 @@
import "ecc/edwardsAdd" as add;
import "ecc/edwardsScalarMult" as multiply;
import "utils/pack/bool/nonStrictUnpack256" as unpack256;
from "ecc/babyjubjubParams" import BabyJubJubParams;
// Verifies that the point is not one of the low-order points.
// If any of the points is multiplied by the cofactor, the resulting point
// will be infinity.
// Returns true if the point is not one of the low-order points, false otherwise.
// Curve parameters are defined with the last argument
// https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166
def main(field[2] pt, BabyJubJubParams context) -> bool {
field cofactor = context.JUBJUB_C;
assert(cofactor == 8);
// Co-factor currently hard-coded to 8 for efficiency reasons
// See discussion here: https://github.com/Zokrates/ZoKrates/pull/301#discussion_r267203391
// Generic code:
// bool[256] cofactorExponent = unpack256(cofactor);
// field[2] ptExp = multiply(cofactorExponent, pt, context);
field[2] mut ptExp = add(pt, pt, context); // 2*pt
ptExp = add(ptExp, ptExp, context); // 4*pt
ptExp = add(ptExp, ptExp, context); // 8*pt
return !(ptExp[0] == 0 && ptExp[1] == 1);
}

View File

@ -0,0 +1,26 @@
import "ecc/edwardsAdd" as add;
import "ecc/edwardsOnCurve" as onCurve;
from "ecc/babyjubjubParams" import BabyJubJubParams;
// Function that implements scalar multiplication for a fixed base point
// Curve parameters are defined with the last argument
// The exponent is hard-coded to a 256bit scalar, hence we allow wrapping around the group for certain
// curve parameters.
// Note that the exponent array is not check to be boolean in this gadget
// Reference: https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/fs.rs#L555
def main(bool[256] exponent, field[2] pt, BabyJubJubParams context) -> field[2] {
field[2] infinity = context.INFINITY;
field[2] mut doubledP = pt;
field[2] mut accumulatedP = infinity;
for u32 i in 0..256 {
u32 j = 255 - i;
field[2] candidateP = add(accumulatedP, doubledP, context);
accumulatedP = exponent[j] ? candidateP : accumulatedP;
doubledP = add(doubledP, doubledP, context);
}
assert(onCurve(accumulatedP, context));
return accumulatedP;
}

View File

@ -0,0 +1,28 @@
import "ecc/edwardsAdd" as add;
import "ecc/edwardsScalarMult" as multiply;
import "utils/pack/bool/nonStrictUnpack256" as unpack256;
from "ecc/babyjubjubParams" import BabyJubJubParams;
/// Verifies match of a given public/private keypair.
///
/// Checks if the following equation holds for the provided keypair:
/// pk = sk*G
/// where G is the chosen base point of the subgroup
/// and * denotes scalar multiplication in the subgroup
///
/// Arguments:
/// pk: Curve point. Public key.
/// sk: Field element. Private key.
/// context: Curve parameters (including generator G) used to create keypair.
///
/// Returns:
/// Return true for pk/sk being a valid keypair, false otherwise.
def main(field[2] pk, field sk, BabyJubJubParams context) -> bool {
field[2] G = [context.Gu, context.Gv];
bool[256] skBits = unpack256(sk);
field[2] ptExp = multiply(skBits, G, context);
bool out = ptExp[0] == pk[0] && ptExp[1] == pk[1];
return out;
}

View File

@ -0,0 +1,4 @@
from "EMBED" import FIELD_SIZE_IN_BITS;
const field FIELD_MIN = 0;
const field FIELD_MAX = -1;

View File

@ -0,0 +1,5 @@
import "hashes/blake2/blake2s_p" as blake2s_p;
def main<K>(u32[K][16] input) -> u32[8] {
return blake2s_p(input, [0; 2]);
}

View File

@ -0,0 +1,117 @@
// https://tools.ietf.org/html/rfc7693
import "utils/casts/u32_to_bits";
import "utils/casts/u32_from_bits";
// Initialization Vector, section 2.6.
const u32[8] IV = [
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
];
// Message Schedule SIGMA, section 2.7.
const u32[10][16] SIGMA = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
[11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
[7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
[9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
[2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
[12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
[13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
[6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
[10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0]
];
// right rotation
def rotr32<N>(u32 x) -> u32 {
return (x >> N) | (x << (32 - N));
}
// change endianness
def swap_u32(u32 val) -> u32 {
return (val << 24) | \
((val << 8) & 0x00ff0000) | \
((val >> 8) & 0x0000ff00) | \
((val >> 24) & 0x000000ff);
}
def mixing_g(u32[16] mut v, u32 a, u32 b, u32 c, u32 d, u32 x, u32 y) -> u32[16] {
v[a] = (v[a] + v[b] + x);
v[d] = rotr32::<16>(v[d] ^ v[a]);
v[c] = (v[c] + v[d]);
v[b] = rotr32::<12>(v[b] ^ v[c]);
v[a] = (v[a] + v[b] + y);
v[d] = rotr32::<8>(v[d] ^ v[a]);
v[c] = (v[c] + v[d]);
v[b] = rotr32::<7>(v[b] ^ v[c]);
return v;
}
def blake2s_compression(u32[8] mut h, u32[16] m, u32[2] t, bool last) -> u32[8] {
u32[16] mut v = [...h, ...IV];
v[12] = v[12] ^ t[0];
v[13] = v[13] ^ t[1];
v[14] = last ? v[14] ^ 0xFFFFFFFF : v[14];
for u32 i in 0..10 {
u32[16] s = SIGMA[i];
v = mixing_g(v, 0, 4, 8, 12, m[s[0]], m[s[1]]);
v = mixing_g(v, 1, 5, 9, 13, m[s[2]], m[s[3]]);
v = mixing_g(v, 2, 6, 10, 14, m[s[4]], m[s[5]]);
v = mixing_g(v, 3, 7, 11, 15, m[s[6]], m[s[7]]);
v = mixing_g(v, 0, 5, 10, 15, m[s[8]], m[s[9]]);
v = mixing_g(v, 1, 6, 11, 12, m[s[10]], m[s[11]]);
v = mixing_g(v, 2, 7, 8, 13, m[s[12]], m[s[13]]);
v = mixing_g(v, 3, 4, 9, 14, m[s[14]], m[s[15]]);
}
for u32 i in 0..8 {
h[i] = h[i] ^ v[i] ^ v[i + 8];
}
return h;
}
def main<K>(u32[K][16] mut input, u32[2] p) -> u32[8] {
u32[8] mut h = [
IV[0] ^ 0x01010000 ^ 0x00000020,
IV[1],
IV[2],
IV[3],
IV[4],
IV[5],
IV[6] ^ swap_u32(p[0]),
IV[7] ^ swap_u32(p[1])
];
u32 mut t0 = 0;
u32 mut t1 = 0;
// change endianness of inputs from big endian to little endian
for u32 i in 0..K {
for u32 j in 0..16 {
input[i][j] = swap_u32(input[i][j]);
}
}
for u32 i in 0..K-1 {
t0 = (i + 1) * 64;
t1 = t0 == 0 ? t1 + 1 : t1;
h = blake2s_compression(h, input[i], [t0, t1], false);
}
t0 = t0 + 64;
t1 = t0 == 0 ? t1 + 1 : t1;
h = blake2s_compression(h, input[K - 1], [t0, t1], true);
// change endianness of output from little endian to big endian
for u32 i in 0..8 {
h[i] = swap_u32(h[i]);
}
return h;
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[28] {
return keccak::<_, 28>(input, 0x01);
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[32] {
return keccak::<_, 32>(input, 0x01);
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[48] {
return keccak::<_, 48>(input, 0x01);
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[64] {
return keccak::<_, 64>(input, 0x01);
}

View File

@ -0,0 +1,161 @@
// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
// based on keccak-f[1600] permutation
import "utils/casts/u8_to_bits";
import "utils/casts/u8_from_bits";
import "utils/casts/u64_to_bits";
import "utils/casts/u64_from_bits";
const u32[24] RHO = [
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
];
const u32[24] PI = [
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
];
const u64[24] RC = [
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
];
// left rotation
def rotl64(u64 x, u32 n) -> u64 {
return ((x << n) | (x >> (64 - n)));
}
// change endianness
def swap_u64(u64 mut val) -> u64 {
val = ((val << 8) & 0xFF00FF00FF00FF00) | ((val >> 8) & 0x00FF00FF00FF00FF);
val = ((val << 16) & 0xFFFF0000FFFF0000) | ((val >> 16) & 0x0000FFFF0000FFFF);
return (val << 32) | (val >> 32);
}
// compression function
def keccakf(u64[25] mut st) -> u64[25] {
u64[5] mut bc = [0; 5];
u64 mut t = 0;
for u32 i in 0..25 {
st[i] = swap_u64(st[i]);
}
for u32 r in 0..24 {
// theta
for u32 i in 0..5 {
bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
}
for u32 i in 0..5 {
t = bc[(i + 4) % 5] ^ rotl64(bc[(i + 1) % 5], 1);
for u32 j in 0..5 {
st[(j * 5) + i] = st[(j * 5) + i] ^ t;
}
}
t = st[1];
// rho pi
for u32 i in 0..24 {
u32 j = PI[i];
bc[0] = st[j];
st[j] = rotl64(t, RHO[i]);
t = bc[0];
}
// chi
for u32 i in 0..5 {
for u32 j in 0..5 {
bc[j] = st[(i * 5) + j];
}
for u32 j in 0..5 {
u32 p = (i * 5) + j;
st[p] = st[p] ^ (!bc[(j + 1) % 5] & bc[(j + 2) % 5]);
}
}
// iota
st[0] = st[0] ^ RC[r];
}
for u32 i in 0..25 {
st[i] = swap_u64(st[i]);
}
return st;
}
def u64_from_u8_array(u8[8] input) -> u64 {
bool[64] bits = [
...u8_to_bits(input[0]),
...u8_to_bits(input[1]),
...u8_to_bits(input[2]),
...u8_to_bits(input[3]),
...u8_to_bits(input[4]),
...u8_to_bits(input[5]),
...u8_to_bits(input[6]),
...u8_to_bits(input[7])
];
return u64_from_bits(bits);
}
def u64_to_u8_array(u64 input) -> u8[8] {
bool[64] bits = u64_to_bits(input);
return [
u8_from_bits(bits[0..8]),
u8_from_bits(bits[8..16]),
u8_from_bits(bits[16..24]),
u8_from_bits(bits[24..32]),
u8_from_bits(bits[32..40]),
u8_from_bits(bits[40..48]),
u8_from_bits(bits[48..56]),
u8_from_bits(bits[56..64])
];
}
def to_bytes(u64[25] input) -> u8[200] {
u8[200] mut output = [0; 200];
for u32 i in 0..25 {
u8[8] t = u64_to_u8_array(input[i]);
for u32 j in 0..8 {
output[i * 8 + j] = t[j];
}
}
return output;
}
def from_bytes(u8[200] input) -> u64[25] {
u64[25] mut output = [0; 25];
for u32 i in 0..25 {
output[i] = u64_from_u8_array(input[i*8..i*8+8]);
}
return output;
}
def main<N, W>(u8[N] mut input, u8 delim) -> u8[W] {
u8[200] mut b = [0; 200];
u32 rate = 200 - (2 * W);
u32 mut pt = 0;
// update
for u32 i in 0..N {
b[pt] = b[pt] ^ input[i];
pt = (pt + 1) % rate;
b = pt == 0 ? to_bytes(keccakf(from_bytes(b))) : b;
}
// finalize
b[pt] = b[pt] ^ delim;
b[rate - 1] = b[rate - 1] ^ 0x80;
b = to_bytes(keccakf(from_bytes(b)));
return b[..W];
}

View File

@ -0,0 +1,112 @@
const field[91] C = [
0,
20888961410941983456478427210666206549300505294776164667214940546594746570981,
15265126113435022738560151911929040668591755459209400716467504685752745317193,
8334177627492981984476504167502758309043212251641796197711684499645635709656,
1374324219480165500871639364801692115397519265181803854177629327624133579404,
11442588683664344394633565859260176446561886575962616332903193988751292992472,
2558901189096558760448896669327086721003508630712968559048179091037845349145,
11189978595292752354820141775598510151189959177917284797737745690127318076389,
3262966573163560839685415914157855077211340576201936620532175028036746741754,
17029914891543225301403832095880481731551830725367286980611178737703889171730,
4614037031668406927330683909387957156531244689520944789503628527855167665518,
19647356996769918391113967168615123299113119185942498194367262335168397100658,
5040699236106090655289931820723926657076483236860546282406111821875672148900,
2632385916954580941368956176626336146806721642583847728103570779270161510514,
17691411851977575435597871505860208507285462834710151833948561098560743654671,
11482807709115676646560379017491661435505951727793345550942389701970904563183,
8360838254132998143349158726141014535383109403565779450210746881879715734773,
12663821244032248511491386323242575231591777785787269938928497649288048289525,
3067001377342968891237590775929219083706800062321980129409398033259904188058,
8536471869378957766675292398190944925664113548202769136103887479787957959589,
19825444354178182240559170937204690272111734703605805530888940813160705385792,
16703465144013840124940690347975638755097486902749048533167980887413919317592,
13061236261277650370863439564453267964462486225679643020432589226741411380501,
10864774797625152707517901967943775867717907803542223029967000416969007792571,
10035653564014594269791753415727486340557376923045841607746250017541686319774,
3446968588058668564420958894889124905706353937375068998436129414772610003289,
4653317306466493184743870159523234588955994456998076243468148492375236846006,
8486711143589723036499933521576871883500223198263343024003617825616410932026,
250710584458582618659378487568129931785810765264752039738223488321597070280,
2104159799604932521291371026105311735948154964200596636974609406977292675173,
16313562605837709339799839901240652934758303521543693857533755376563489378839,
6032365105133504724925793806318578936233045029919447519826248813478479197288,
14025118133847866722315446277964222215118620050302054655768867040006542798474,
7400123822125662712777833064081316757896757785777291653271747396958201309118,
1744432620323851751204287974553233986555641872755053103823939564833813704825,
8316378125659383262515151597439205374263247719876250938893842106722210729522,
6739722627047123650704294650168547689199576889424317598327664349670094847386,
21211457866117465531949733809706514799713333930924902519246949506964470524162,
13718112532745211817410303291774369209520657938741992779396229864894885156527,
5264534817993325015357427094323255342713527811596856940387954546330728068658,
18884137497114307927425084003812022333609937761793387700010402412840002189451,
5148596049900083984813839872929010525572543381981952060869301611018636120248,
19799686398774806587970184652860783461860993790013219899147141137827718662674,
19240878651604412704364448729659032944342952609050243268894572835672205984837,
10546185249390392695582524554167530669949955276893453512788278945742408153192,
5507959600969845538113649209272736011390582494851145043668969080335346810411,
18177751737739153338153217698774510185696788019377850245260475034576050820091,
19603444733183990109492724100282114612026332366576932662794133334264283907557,
10548274686824425401349248282213580046351514091431715597441736281987273193140,
1823201861560942974198127384034483127920205835821334101215923769688644479957,
11867589662193422187545516240823411225342068709600734253659804646934346124945,
18718569356736340558616379408444812528964066420519677106145092918482774343613,
10530777752259630125564678480897857853807637120039176813174150229243735996839,
20486583726592018813337145844457018474256372770211860618687961310422228379031,
12690713110714036569415168795200156516217175005650145422920562694422306200486,
17386427286863519095301372413760745749282643730629659997153085139065756667205,
2216432659854733047132347621569505613620980842043977268828076165669557467682,
6309765381643925252238633914530877025934201680691496500372265330505506717193,
20806323192073945401862788605803131761175139076694468214027227878952047793390,
4037040458505567977365391535756875199663510397600316887746139396052445718861,
19948974083684238245321361840704327952464170097132407924861169241740046562673,
845322671528508199439318170916419179535949348988022948153107378280175750024,
16222384601744433420585982239113457177459602187868460608565289920306145389382,
10232118865851112229330353999139005145127746617219324244541194256766741433339,
6699067738555349409504843460654299019000594109597429103342076743347235369120,
6220784880752427143725783746407285094967584864656399181815603544365010379208,
6129250029437675212264306655559561251995722990149771051304736001195288083309,
10773245783118750721454994239248013870822765715268323522295722350908043393604,
4490242021765793917495398271905043433053432245571325177153467194570741607167,
19596995117319480189066041930051006586888908165330319666010398892494684778526,
837850695495734270707668553360118467905109360511302468085569220634750561083,
11803922811376367215191737026157445294481406304781326649717082177394185903907,
10201298324909697255105265958780781450978049256931478989759448189112393506592,
13564695482314888817576351063608519127702411536552857463682060761575100923924,
9262808208636973454201420823766139682381973240743541030659775288508921362724,
173271062536305557219323722062711383294158572562695717740068656098441040230,
18120430890549410286417591505529104700901943324772175772035648111937818237369,
20484495168135072493552514219686101965206843697794133766912991150184337935627,
19155651295705203459475805213866664350848604323501251939850063308319753686505,
11971299749478202793661982361798418342615500543489781306376058267926437157297,
18285310723116790056148596536349375622245669010373674803854111592441823052978,
7069216248902547653615508023941692395371990416048967468982099270925308100727,
6465151453746412132599596984628739550147379072443683076388208843341824127379,
16143532858389170960690347742477978826830511669766530042104134302796355145785,
19362583304414853660976404410208489566967618125972377176980367224623492419647,
1702213613534733786921602839210290505213503664731919006932367875629005980493,
10781825404476535814285389902565833897646945212027592373510689209734812292327,
4212716923652881254737947578600828255798948993302968210248673545442808456151,
7594017890037021425366623750593200398174488805473151513558919864633711506220,
18979889247746272055963929241596362599320706910852082477600815822482192194401,
13602139229813231349386885113156901793661719180900395818909719758150455500533
];
def main<R>(field x_in, field k) -> field {
field mut t = 0;
field[R] mut t2 = [0; R];
field[R] mut t4 = [0; R];
field[R] mut t6 = [0; R];
field[R] mut t7 = [0; R]; // we define t7 length +1 to avoid conditional branching
for u32 i in 0..R {
u32 i2 = i == 0 ? 0 : i - 1;
t = i == 0 ? k + x_in : k + t7[i2] + C[i];
t2[i] = t * t;
t4[i] = t2[i] * t2[i];
t6[i] = t4[i] * t2[i];
t7[i] = t6[i] * t;
}
return t6[R - 1] * t + k;
}

View File

@ -0,0 +1,250 @@
// MiMCFeistel configured with 220 rounds
const u32 R = 220;
const field[R] IV = [
0,
7120861356467848435263064379192047478074060781135320967663101236819528304084,
5024705281721889198577876690145313457398658950011302225525409148828000436681,
17980351014018068290387269214713820287804403312720763401943303895585469787384,
19886576439381707240399940949310933992335779767309383709787331470398675714258,
1213715278223786725806155661738676903520350859678319590331207960381534602599,
18162138253399958831050545255414688239130588254891200470934232514682584734511,
7667462281466170157858259197976388676420847047604921256361474169980037581876,
7207551498477838452286210989212982851118089401128156132319807392460388436957,
9864183311657946807255900203841777810810224615118629957816193727554621093838,
4798196928559910300796064665904583125427459076060519468052008159779219347957,
17387238494588145257484818061490088963673275521250153686214197573695921400950,
10005334761930299057035055370088813230849810566234116771751925093634136574742,
11897542014760736209670863723231849628230383119798486487899539017466261308762,
16771780563523793011283273687253985566177232886900511371656074413362142152543,
749264854018824809464168489785113337925400687349357088413132714480582918506,
3683645737503705042628598550438395339383572464204988015434959428676652575331,
7556750851783822914673316211129907782679509728346361368978891584375551186255,
20391289379084797414557439284689954098721219201171527383291525676334308303023,
18146517657445423462330854383025300323335289319277199154920964274562014376193,
8080173465267536232534446836148661251987053305394647905212781979099916615292,
10796443006899450245502071131975731672911747129805343722228413358507805531141,
5404287610364961067658660283245291234008692303120470305032076412056764726509,
4623894483395123520243967718315330178025957095502546813929290333264120223168,
16845753148201777192406958674202574751725237939980634861948953189320362207797,
4622170486584704769521001011395820886029808520586507873417553166762370293671,
16688277490485052681847773549197928630624828392248424077804829676011512392564,
11878652861183667748838188993669912629573713271883125458838494308957689090959,
2436445725746972287496138382764643208791713986676129260589667864467010129482,
1888098689545151571063267806606510032698677328923740058080630641742325067877,
148924106504065664829055598316821983869409581623245780505601526786791681102,
18875020877782404439294079398043479420415331640996249745272087358069018086569,
15189693413320228845990326214136820307649565437237093707846682797649429515840,
19669450123472657781282985229369348220906547335081730205028099210442632534079,
5521922218264623411380547905210139511350706092570900075727555783240701821773,
4144769320246558352780591737261172907511489963810975650573703217887429086546,
10097732913112662248360143041019433907849917041759137293018029019134392559350,
1720059427972723034107765345743336447947522473310069975142483982753181038321,
6302388219880227251325608388535181451187131054211388356563634768253301290116,
6745410632962119604799318394592010194450845483518862700079921360015766217097,
10858157235265583624235850660462324469799552996870780238992046963007491306222,
20241898894740093733047052816576694435372877719072347814065227797906130857593,
10165780782761211520836029617746977303303335603838343292431760011576528327409,
2832093654883670345969792724123161241696170611611744759675180839473215203706,
153011722355526826233082383360057587249818749719433916258246100068258954737,
20196970640587451358539129330170636295243141659030208529338914906436009086943,
3180973917010545328313139835982464870638521890385603025657430208141494469656,
17198004293191777441573635123110935015228014028618868252989374962722329283022,
7642160509228669138628515458941659189680509753651629476399516332224325757132,
19346204940546791021518535594447257347218878114049998691060016493806845179755,
11501810868606870391127866188394535330696206817602260610801897042898616817272,
3113973447392053821824427670386252797811804954746053461397972968381571297505,
6545064306297957002139416752334741502722251869537551068239642131448768236585,
5203908808704813498389265425172875593837960384349653691918590736979872578408,
2246692432011290582160062129070762007374502637007107318105405626910313810224,
11760570435432189127645691249600821064883781677693087773459065574359292849137,
5543749482491340532547407723464609328207990784853381797689466144924198391839,
8837549193990558762776520822018694066937602576881497343584903902880277769302,
12855514863299373699594410385788943772765811961581749194183533625311486462501,
5363660674689121676875069134269386492382220935599781121306637800261912519729,
13162342403579303950549728848130828093497701266240457479693991108217307949435,
916941639326869583414469202910306428966657806899788970948781207501251816730,
15618589556584434434009868216186115416835494805174158488636000580759692174228,
8959562060028569701043973060670353733575345393653685776974948916988033453971,
16390754464333401712265575949874369157699293840516802426621216808905079127650,
168282396747788514908709091757591226095443902501365500003618183905496160435,
8327443473179334761744301768309008451162322941906921742120510244986704677004,
17213012626801210615058753489149961717422101711567228037597150941152495100640,
10394369641533736715250242399198097296122982486516256408681925424076248952280,
17784386835392322654196171115293700800825771210400152504776806618892170162248,
16533189939837087893364000390641148516479148564190420358849587959161226782982,
18725396114211370207078434315900726338547621160475533496863298091023511945076,
7132325028834551397904855671244375895110341505383911719294705267624034122405,
148317947440800089795933930720822493695520852448386394775371401743494965187,
19001050671757720352890779127693793630251266879994702723636759889378387053056,
18824274411769830274877839365728651108434404855803844568234862945613766611460,
12771414330193951156383998390424063470766226667986423961689712557338777174205,
11332046574800279729678603488745295198038913503395629790213378101166488244657,
9607550223176946388146938069307456967842408600269548190739947540821716354749,
8756385288462344550200229174435953103162307705310807828651304665320046782583,
176061952957067086877570020242717222844908281373122372938833890096257042779,
12200212977482648306758992405065921724409841940671166017620928947866825250857,
10868453624107875516866146499877130701929063632959660262366632833504750028858,
2016095394399807253596787752134573207202567875457560571095586743878953450738,
21815578223768330433802113452339488275704145896544481092014911825656390567514,
4923772847693564777744725640710197015181591950368494148029046443433103381621,
1813584943682214789802230765734821149202472893379265320098816901270224589984,
10810123816265612772922113403831964815724109728287572256602010709288980656498,
1153669123397255702524721206511185557982017410156956216465120456256288427021,
5007518659266430200134478928344522649876467369278722765097865662497773767152,
2511432546938591792036639990606464315121646668029252285288323664350666551637,
32883284540320451295484135704808083452381176816565850047310272290579727564,
10484856914279112612610993418405543310546746652738541161791501150994088679557,
2026733759645519472558796412979210009170379159866522399881566309631434814953,
14731806221235869882801331463708736361296174006732553130708107037190460654379,
14740327483193277147065845135561988641238516852487657117813536909482068950652,
18787428285295558781869865751953016580493190547148386433580291216673009884554,
3804047064713122820157099453648459188816376755739202017447862327783289895072,
16709604795697901641948603019242067672006293290826991671766611326262532802914,
11061717085931490100602849654034280576915102867237101935487893025907907250695,
2821730726367472966906149684046356272806484545281639696873240305052362149654,
17467794879902895769410571945152708684493991588672014763135370927880883292655,
1571520786233540988201616650622796363168031165456869481368085474420849243232,
10041051776251223165849354194892664881051125330236567356945669006147134614302,
3981753758468103976812813304477670033098707002886030847251581853700311567551,
4365864398105436789177703571412645548020537580493599380018290523813331678900,
2391801327305361293476178683853802679507598622000359948432171562543560193350,
214219368547551689972421167733597094823289857206402800635962137077096090722,
18192064100315141084242006659317257023098826945893371479835220462302399655674,
15487549757142039139328911515400805508248576685795694919457041092150651939253,
10142447197759703415402259672441315777933858467700579946665223821199077641122,
11246573086260753259993971254725613211193686683988426513880826148090811891866,
6574066859860991369704567902211886840188702386542112593710271426704432301235,
11311085442652291634822798307831431035776248927202286895207125867542470350078,
20977948360215259915441258687649465618185769343138135384346964466965010873779,
792781492853909872425531014397300057232399608769451037135936617996830018501,
5027602491523497423798779154966735896562099398367163998686335127580757861872,
14595204575654316237672764823862241845410365278802914304953002937313300553572,
13973538843621261113924259058427434053808430378163734641175100160836376897004,
16395063164993626722686882727042150241125309409717445381854913964674649318585,
8465768840047024550750516678171433288207841931251654898809033371655109266663,
21345603324471810861925019445720576814602636473739003852898308205213912255830,
21171984405852590343970239018692870799717057961108910523876770029017785940991,
10761027113757988230637066281488532903174559953630210849190212601991063767647,
6678298831065390834922566306988418588227382406175769592902974103663687992230,
4993662582188632374202316265508850988596880036291765531885657575099537176757,
18364168158495573675698600238443218434246806358811328083953887470513967121206,
3506345610354615013737144848471391553141006285964325596214723571988011984829,
248732676202643792226973868626360612151424823368345645514532870586234380100,
10090204501612803176317709245679152331057882187411777688746797044706063410969,
21297149835078365363970699581821844234354988617890041296044775371855432973500,
16729368143229828574342820060716366330476985824952922184463387490091156065099,
4467191506765339364971058668792642195242197133011672559453028147641428433293,
8677548159358013363291014307402600830078662555833653517843708051504582990832,
1022951765127126818581466247360193856197472064872288389992480993218645055345,
1888195070251580606973417065636430294417895423429240431595054184472931224452,
4221265384902749246920810956363310125115516771964522748896154428740238579824,
2825393571154632139467378429077438870179957021959813965940638905853993971879,
19171031072692942278056619599721228021635671304612437350119663236604712493093,
10780807212297131186617505517708903709488273075252405602261683478333331220733,
18230936781133176044598070768084230333433368654744509969087239465125979720995,
16901065971871379877929280081392692752968612240624985552337779093292740763381,
146494141603558321291767829522948454429758543710648402457451799015963102253,
2492729278659146790410698334997955258248120870028541691998279257260289595548,
2204224910006646535594933495262085193210692406133533679934843341237521233504,
16062117410185840274616925297332331018523844434907012275592638570193234893570,
5894928453677122829055071981254202951712129328678534592916926069506935491729,
4947482739415078212217504789923078546034438919537985740403824517728200332286,
16143265650645676880461646123844627780378251900510645261875867423498913438066,
397690828254561723549349897112473766901585444153303054845160673059519614409,
11272653598912269895509621181205395118899451234151664604248382803490621227687,
15566927854306879444693061574322104423426072650522411176731130806720753591030,
14222898219492484180162096141564251903058269177856173968147960855133048449557,
16690275395485630428127725067513114066329712673106153451801968992299636791385,
3667030990325966886479548860429670833692690972701471494757671819017808678584,
21280039024501430842616328642522421302481259067470872421086939673482530783142,
15895485136902450169492923978042129726601461603404514670348703312850236146328,
7733050956302327984762132317027414325566202380840692458138724610131603812560,
438123800976401478772659663183448617575635636575786782566035096946820525816,
814913922521637742587885320797606426167962526342166512693085292151314976633,
12368712287081330853637674140264759478736012797026621876924395982504369598764,
2494806857395134874309386694756263421445039103814920780777601708371037591569,
16101132301514338989512946061786320637179843435886825102406248183507106312877,
6252650284989960032925831409804233477770646333900692286731621844532438095656,
9277135875276787021836189566799935097400042171346561246305113339462708861695,
10493603554686607050979497281838644324893776154179810893893660722522945589063,
8673089750662709235894359384294076697329948991010184356091130382437645649279,
9558393272910366944245875920138649617479779893610128634419086981339060613250,
19012287860122586147374214541764572282814469237161122489573881644994964647218,
9783723818270121678386992630754842961728702994964214799008457449989291229500,
15550788416669474113213749561488122552422887538676036667630838378023479382689,
15016165746156232864069722572047169071786333815661109750860165034341572904221,
6506225705710197163670556961299945987488979904603689017479840649664564978574,
10796631184889302076168355684722130903785890709107732067446714470783437829037,
19871836214837460419845806980869387567383718044439891735114283113359312279540,
20871081766843466343749609089986071784031203517506781251203251608363835140622,
5100105771517691442278432864090229416166996183792075307747582375962855820797,
8777887112076272395250620301071581171386440850451972412060638225741125310886,
5300440870136391278944213332144327695659161151625757537632832724102670898756,
1205448543652932944633962232545707633928124666868453915721030884663332604536,
5542499997310181530432302492142574333860449305424174466698068685590909336771,
11028094245762332275225364962905938096659249161369092798505554939952525894293,
19187314764836593118404597958543112407224947638377479622725713735224279297009,
17047263688548829001253658727764731047114098556534482052135734487985276987385,
19914849528178967155534624144358541535306360577227460456855821557421213606310,
2929658084700714257515872921366736697080475676508114973627124569375444665664,
15092262360719700162343163278648422751610766427236295023221516498310468956361,
21578580340755653236050830649990190843552802306886938815497471545814130084980,
1258781501221760320019859066036073675029057285507345332959539295621677296991,
3819598418157732134449049289585680301176983019643974929528867686268702720163,
8653175945487997845203439345797943132543211416447757110963967501177317426221,
6614652990340435611114076169697104582524566019034036680161902142028967568142,
19212515502973904821995111796203064175854996071497099383090983975618035391558,
18664315914479294273286016871365663486061896605232511201418576829062292269769,
11498264615058604317482574216318586415670903094838791165247179252175768794889,
10814026414212439999107945133852431304483604215416531759535467355316227331774,
17566185590731088197064706533119299946752127014428399631467913813769853431107,
14016139747289624978792446847000951708158212463304817001882956166752906714332,
8242601581342441750402731523736202888792436665415852106196418942315563860366,
9244680976345080074252591214216060854998619670381671198295645618515047080988,
12216779172735125538689875667307129262237123728082657485828359100719208190116,
10702811721859145441471328511968332847175733707711670171718794132331147396634,
6479667912792222539919362076122453947926362746906450079329453150607427372979,
15117544653571553820496948522381772148324367479772362833334593000535648316185,
6842203153996907264167856337497139692895299874139131328642472698663046726780,
12732823292801537626009139514048596316076834307941224506504666470961250728055,
6936272626871035740815028148058841877090860312517423346335878088297448888663,
17297554111853491139852678417579991271009602631577069694853813331124433680030,
16641596134749940573104316021365063031319260205559553673368334842484345864859,
7400481189785154329569470986896455371037813715804007747228648863919991399081,
2273205422216987330510475127669563545720586464429614439716564154166712854048,
15162538063742142685306302282127534305212832649282186184583465569986719234456,
5628039096440332922248578319648483863204530861778160259559031331287721255522,
16085392195894691829567913404182676871326863890140775376809129785155092531260,
14227467863135365427954093998621993651369686288941275436795622973781503444257,
18224457394066545825553407391290108485121649197258948320896164404518684305122,
274945154732293792784580363548970818611304339008964723447672490026510689427,
11050822248291117548220126630860474473945266276626263036056336623671308219529,
2119542016932434047340813757208803962484943912710204325088879681995922344971,
0
];
def main(field xL_in, field xR_in, field k) -> field[2] {
field[R] mut t2 = [0; R];
field[R] mut t4 = [0; R];
field[R] mut xL = [0; R];
field[R] mut xR = [0; R];
field mut t = 0;
field mut c = 0;
for u32 i in 0..R {
u32 j = i == 0 ? 0 : i - 1;
c = IV[i];
t = i == 0 ? k + xL_in : k + xL[j] + c;
t2[i] = t * t;
t4[i] = t2[i] * t2[i];
xL[i] = i < R - 1 ? (i == 0 ? xR_in + t4[i] * t : xR[j] + t4[i] * t) : xL[j];
xR[i] = i < R - 1 ? (i == 0 ? xL_in : xL[j]) : xR[j] + t4[i] * t;
}
return [xL[R - 1], xR[R - 1]];
}

View File

@ -0,0 +1,20 @@
import "./mimcFeistel" as MiMCFeistel;
def main<nInputs, nOutputs>(field[nInputs] ins, field k) -> field[nOutputs] {
field[nInputs + nOutputs - 1][2] mut S = [[0; 2]; nInputs + nOutputs - 1];
field[nOutputs] mut outs = [0; nOutputs];
for u32 i in 0..nInputs {
u32 j = i == 0 ? 0 : i - 1;
S[i] = i == 0 ? MiMCFeistel(ins[0], 0, k) : MiMCFeistel(S[j][0] + ins[i], S[j][1], k);
}
outs[0] = S[nInputs - 1][0];
for u32 i in 0..(nOutputs - 1) {
S[nInputs + i] = MiMCFeistel(S[nInputs + i - 1][0], S[nInputs + i - 1][1], k);
outs[i + 1] = S[nInputs + i][0];
}
return outs;
}

View File

@ -0,0 +1,36 @@
import "./512bitBool.zok" as pedersen;
import "utils/casts/u32_to_bits" as to_bits;
import "utils/casts/u32_from_bits" as from_bits;
def main(u32[16] inputs) -> u32[8] {
bool[512] e = [
...to_bits(inputs[0]),
...to_bits(inputs[1]),
...to_bits(inputs[2]),
...to_bits(inputs[3]),
...to_bits(inputs[4]),
...to_bits(inputs[5]),
...to_bits(inputs[6]),
...to_bits(inputs[7]),
...to_bits(inputs[8]),
...to_bits(inputs[9]),
...to_bits(inputs[10]),
...to_bits(inputs[11]),
...to_bits(inputs[12]),
...to_bits(inputs[13]),
...to_bits(inputs[14]),
...to_bits(inputs[15])
];
bool[256] aC = pedersen(e);
return [
from_bits(aC[0..32]),
from_bits(aC[32..64]),
from_bits(aC[64..96]),
from_bits(aC[96..128]),
from_bits(aC[128..160]),
from_bits(aC[160..192]),
from_bits(aC[192..224]),
from_bits(aC[224..256])
];
}

View File

@ -0,0 +1,714 @@
import "utils/multiplexer/lookup3bitSigned" as sel3s;
import "utils/multiplexer/lookup2bit" as sel2;
import "ecc/edwardsAdd" as add;
import "ecc/edwardsCompress" as edwardsCompress;
from "ecc/babyjubjubParams" import BABYJUBJUB_PARAMS;
// Code to export generators used in this example:
// import bitstring
// from zokrates_pycrypto.gadgets.pedersenHasher import PedersenHasher
// import numpy as np
// #%%
// entropy = np.random.bytes(64)
// hasher = PedersenHasher("test")
// hasher.hash_bytes(entropy)
// print(hasher.dsl_code)
def main(bool[512] inputs) -> bool[256] {
bool[513] e = [
...inputs,
false
];
field[2] mut a = BABYJUBJUB_PARAMS.INFINITY; // Infinity
field mut cx = 0;
field mut cy = 0;
// Round 0
cx = sel3s([e[0], e[1], e[2]], [13418723823902222986275588345615650707197303761863176429873001977640541977977, 8366451672790208592553809639953117385619257483837439526516290319251622927412, 1785026334726838136757054176272745265857971873904476677125553010508875025629, 15763987975760561753692294837740043971877392788040801334205375164715487005236]);
cy = sel2([e[0], e[1]], [15255921313433251341520743036334816584226787412845488772781699434149539664639, 10916775373885716961512013142444429405184550001421868906213743991404593770484, 18533662942827602783563125901366807026309605479742251601915445402562880550265, 12754584346112149619040942896930712185968371085994381911052593922432846916845]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 1
cx = sel3s([e[3], e[4], e[5]], [10096735692467598736728394557736034054031417419721869067082824451240861468728, 6979151010236415881632946866847657030447196774231162748523315765559549846746, 12137947022495312670974525048647679757468392619153927921382150023166867027471, 10624360821702266736197468438435445939719745367234393212061381062942588576905]);
cy = sel2([e[3], e[4]], [16704592219657141368520262522286248296157931669321735564513068002743507745908, 11518684165372839249156788740134693928233608013641661856685773776747280808438, 21502372109496595498116676984635248026663470429940273577484250291841812814697, 17522620677401472201433112250371604936150385414760411280739362011041111141253]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 2
cx = sel3s([e[6], e[7], e[8]], [13312232735691933658355691628172862856002099081831058080743469900077389848112, 19327977014594608605244544461851908604127577374373936700152837514516831827340, 5965720943494263185596399776343244990255258211404706922145440547143467603204, 11103963817151340664968920805661885925719434417460707046799768750046118166436]);
cy = sel2([e[6], e[7]], [13997829888819279202328839701908695991998552542771378089573544166678617234314, 13691878221338656794058835175667599549759724338245021721239544263931121101102, 706995887987748628352958611569702130644716818339521451078302067359882016752, 15519367213943391783104357888987456282196269996908068205680088855765566529720]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 3
cx = sel3s([e[9], e[10], e[11]], [3514614172108804338031132171140068954832144631243755202685348634084887116595, 21412073555057635706619028382831866089835908408883521913045888015461883281372, 471607086653490738521346129178778785664646799897580486044670851346383461743, 10847495464297569158944970563387929708762967645792327184202073895773051681481]);
cy = sel2([e[9], e[10]], [15464894923367337880246198022819299804461472054752016232660084768002214822896, 12567819427817222147810760128898363854788230435988968217407844445582977743495, 12262870457786134457367539925912446664295463121045105711733382320777142547504, 18045012503832343228779780686530560760323693867512598336456499973983304678718]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 4
cx = sel3s([e[12], e[13], e[14]], [15118628380960917951049569119912548662747322287644759811263888312919249703276, 16598886614963769408191675395388471256601718506085533073063821434952573740600, 18985834203956331009360396769407075613873303527461874103999130837255502328872, 4433382535573345454766736182894234755024333432764634149565968221321851794725]);
cy = sel2([e[12], e[13]], [20910093482714196883913434341954530700836700132902516503233669201436063149009, 1519565901492557479831267649363202289903292383838537677400586534724780525304, 10041416515147137792479948105907931790389702515927709045015890740481960188846, 14765380703378616132649352585549040264662795611639979047816682374423451525367]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 5
cx = sel3s([e[15], e[16], e[17]], [12047448614322625640496087488290723061283996543855169192549742347740217312911, 4511402808301687111378591744698422835937202088514472343139677982999770140261, 12163443309105839408816984443621255269615222157093914420088948521258519452383, 3481629181674207202258216324378273648482838926623855453371874690866818821960]);
cy = sel2([e[15], e[16]], [16179347143471683729835238045770641754106645772730542840306059882771262928390, 1330606780692172668576026668607748751348574609524694619904517828208139587545, 21047796364446011793075955655871569603152857270194799075248022968227548164989, 19676582441619193608410544431560207171545714550092005317667230665261246116642]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 6
cx = sel3s([e[18], e[19], e[20]], [12701245173613054114260668542643518710151543759808175831262148773821226772548, 18376560769194320940844431278184909327980744436343482850507604422674089850707, 2108750731998522594975480214785919514173920126687735114472940765769183959289, 8345688345972355310911106597696772464487464098975129504776508629148304380440]);
cy = sel2([e[18], e[19]], [6893882093554801220855651573375911275440312424798351852776449414399981870319, 10206179889544308860397247082680802082921236707029342452958684549094240474070, 20690576727949006946449925807058663187909753260538825130322359335830578756980, 934097825986417774187883244964416516816295235495828890679674782707274540176]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 7
cx = sel3s([e[21], e[22], e[23]], [2944698428855471170284815781705687753367479016293091716206788980482046638948, 13677149007138113141214051970478824544363893133343069459792025336510743485579, 8778584537362078914166751980528033062427878768812683022653464796527206882567, 14187573305341020255138644844606451353103636392771375201751096173736574567883]);
cy = sel2([e[21], e[22]], [17360101552805013843890050881314712134389035043192466182420273655548320239406, 15585069751456986750767880753875189652981026069625633386060310449606941883984, 14103016602951516262329001181468262879087099584460171406752641724802127444882, 20246884593862204796710227582734862797721958090111806492549002716706329529389]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 8
cx = sel3s([e[24], e[25], e[26]], [14561966822440683665541629338358038450751192033904756806839710397580365916408, 9033289676904424897161301113716021195450524279682799709206671901182123388512, 3130553029765252517071677341132737863162584406047933071036994763690628383497, 478748220028687672909774713203680223481010996519205842697362525656305870550]);
cy = sel2([e[24], e[25]], [2103279357051120614300268561700949519576521616178686690761693996681299230890, 20408096719725376095564479959189425244640061563902110565713028117867143533071, 10602190247054189080928144476332888853804880952034975460420247853133904008108, 8904086690633759655814572723164827369823592560037992353159979088242240507753]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 9
cx = sel3s([e[27], e[28], e[29]], [6226499033652114521979121779728984801913588832404495199289210905837818402723, 8038917508002636084872059181598756897599119789741848736002584943229165162988, 2277325821476302201179031013369476744187798789480148846137091219460796268467, 967514222774662330369300003456258491278184516505205753272628639669418183698]);
cy = sel2([e[27], e[28]], [7443974969385276473096219793909172323973358085935860096061435962537700448286, 16080381380787087259419052592465179031841607813350912826860291224363330298665, 7197183980134554514649915487783920553359271769991651108349414168397349372685, 15259375744392791676426881929656094304768076565231411137199656518314416373020]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 10
cx = sel3s([e[30], e[31], e[32]], [7079401365241105225661961622760419818013463250349580158302569256283647306129, 14357098412862251375028337875874646262567035230486208703024315026944432279497, 12132744267560027693690759266151433597852816079588628241106105645480008053825, 16149669420758195925157542983134397690644755714433681232247094526660232442631]);
cy = sel2([e[30], e[31]], [11050535702333135359874644130653446287886435768224627066379760227644857448025, 2102777351898195104147031754958199443749204333224032175429214522075012926330, 4445288497276728579279429434033072747592184765171167503126978668105350002482, 2895400734738526057690008272958539309751728639263619269043890651038357187575]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 11
cx = sel3s([e[33], e[34], e[35]], [20192636532359225751119979205906307972955330178954709766736232115035084682472, 804195338747219623697418198937917828717652612397835452095971237574002648345, 6394431494852440399081028203192653448308162012036135765292083934292810191518, 11939476767684237945975176292664687849983867031644620074465117021204214089848]);
cy = sel2([e[33], e[34]], [17748517956264309916268005941322895780280007418421226047127160997826331847601, 19497513174101598882802026674952900838989414265369078336475842766531805130216, 5620469644231252504463650386222007834239202862082473485080174711171599148975, 5516661986429427386078472422851029350005420782971768428739820651749444868271]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 12
cx = sel3s([e[36], e[37], e[38]], [1324920405111324350836746707883938204858273081019435873511569172015916187999, 15384225309297147198449617653578330654472159141743407174794062987091000857662, 9920404264935487368096005007182799973436766546149561065368669780566156587060, 15254057056535397961799214335179813200885132815863068943475012547021698517077]);
cy = sel2([e[36], e[37]], [16984705452766649815073644511059333480190120433850502120324063182300137456908, 18046160220855048074367913256918233739227589113215101142291000275961918974523, 13094718066881673586455686749880972268909309391825129019088029831712146780775, 17556146601257932451584708078305104848786797650062537873707738860847250565143]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 13
cx = sel3s([e[39], e[40], e[41]], [10184781845128697471817965179509651550812478664395958690225791623061609959495, 5456125639262884825452992858423500073570690895733609235845616173174729575569, 2442835875584110487966438996784695688123609547017380844898154175948468234967, 1507509649954376860384651590722437356078107662975164713418836301939281575419]);
cy = sel2([e[39], e[40]], [12481681651435870984379558646813686612408709833154117210578901875084149402369, 11152008367598826226940260746556525580820232821082556208512958435351250898503, 7567915483885326926315083960846242855523572023844618551872662303018722806760, 20394803059296859730298132333424950360853695629226621934657959417500478188961]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 14
cx = sel3s([e[42], e[43], e[44]], [10680962982327504072121608021689834159178144997131600234373184928312768469752, 2399077467035346531560164705357209055497431901223015425246039711757880798964, 3423125451159866822107483111524543716819043967842944968651561023348340629866, 9942880027482137313328709914157120920632734642771778240985776643385937071731]);
cy = sel2([e[42], e[43]], [4698845013673361363032641974440465619959991809676353365742268606915462346702, 16130578759626193985851427947711894136403468334125608062505774040115700327331, 15972516792261738383725187984065495328469263202118598475958253769706945995080, 7601042727654430423755752301100987459144576573414967660631298823059519301944]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 15
cx = sel3s([e[45], e[46], e[47]], [559099661340368706731458173062937049444139592208939239637572972395409815235, 1445905511768661496314996877214005625534188630127375321650145036638654136508, 12558069540132067621925302006222579198925455408763618011362743955646129467625, 19809789628385980249290251944250230372682953514057413790020001670501854917090]);
cy = sel2([e[45], e[46]], [10744092763718531253355077100374662669098109929848484460119044326894952631009, 3973362040829593578154878010051739631231888449967620092704468180671355813892, 1362015208311760378785201188340495520529554642363760051915563618841646945115, 11588368620504227678083366267185871581602064602621931713732756924598104334083]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 16
cx = sel3s([e[48], e[49], e[50]], [1678013963086824122518234712588270403106471527976328603364788331772512526348, 19217446816753374280163957047166499363370322773252755452762764797217084855190, 18251775792701212313037978569776264038974809413837373677702565241405411946778, 7791054681559787609111187809686247485256130898718509173169053332755413410611]);
cy = sel2([e[48], e[49]], [2187428842929094383038114367392650175780437811274194322303902357941058607339, 8626132368431980635626323475901790012728207722636477570331410763937692048466, 113795593186630447648084123083495614901087109757474270136294009546464903517, 3911253907085777766524239918145094862050185692851156691146764655435644911738]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 17
cx = sel3s([e[51], e[52], e[53]], [12873968423948310899392467568104977730716801401622261861937368089215309803500, 12347009456329688755313379291270351313162786795095345538842244121034639964166, 1453033777281838070082852447488517173632198407446735454517038916605079634444, 11282290315868048695472900994602235661536258445850718305682561140328404797725]);
cy = sel2([e[51], e[52]], [8139007031385157566567411468459940290231498857090568363629902873306461631248, 9142412231629797319569179103935970351107774720462787670615972830568683805984, 12672100925996181868477785977558380430714799944709260345359951721012123501095, 16494953398584179618210238266126209360371451946684386111530845235540890038134]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 18
cx = sel3s([e[54], e[55], e[56]], [7778254495039611795685039895928787457435875136389165268120013630439201169232, 18978376692784498976711790251498129273567483356717340918869164950830208175147, 6786343960634025784864145941287160961224170404722122001422161703472545445301, 963142484718869013546386102939529863406065949253846087785240390647819147126]);
cy = sel2([e[54], e[55]], [7284679595773642123118330714484999203099307921555787993734753019057231440983, 11863181578147413903879545253723831525079414688349285572164796614141056912840, 14506820856835670503131551890617399661938603609062325089041733284980790009293, 4347670008275218338032617206784753933320201662996772040726919225863771514568]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 19
cx = sel3s([e[57], e[58], e[59]], [3630756302007400417952089805331380555952289748859891438940570770932527475452, 4733072488758626584177720052077496914661792393101658203493985364120366268281, 4526910185101338883574479225992287789853409001566403159278561225375682298543, 4955992755917650287600423903671744997417781344631255784951922382765227784141]);
cy = sel2([e[57], e[58]], [16596280733402230599955345374089507399680037832193751466748596443674569931646, 6390381659733151443695336725554471564240651107616043093647301732553182081233, 17125093365984505488419430885232358010204128822674623886572872558984812477756, 7907776458440631594337279500574606181494889317898652109149850067084027888619]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 20
cx = sel3s([e[60], e[61], e[62]], [13428507160783248146944378848829437095621758280249270905793449036777555016842, 10292076501843933688687976934900220205880058108224904881677407523508189156342, 766857404192368568735095124452313950539381046754211726072981073742394879383, 19929977262929097751573344897093024390473135465066154321364399543253519251540]);
cy = sel2([e[60], e[61]], [16698341695430068847582701171147088836738454320587148532489385958997389524692, 15892936434362954902510964691481568586089663041057258511149661842770672240332, 7940515703899915602011570921990242082041971424425808524102519499134803569591, 6891504197906111172381550323513759741804319972496414093225387272302697012664]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 21
cx = sel3s([e[63], e[64], e[65]], [9001788585918405588944162583417858847457169702891113291878897002187678929577, 6471893763677472946002018028525448192731896031469219164732421705849786414080, 6872696243264239672878286181725922526028148800020555100207514569826971690256, 6457059076269833003010871598305386357557482703463879737255688784535353986402]);
cy = sel2([e[63], e[64]], [2208441895306047741608356002988212098270630744976300198681224594148576837458, 18524825154497781981405149991295652940946623352876024366965123296382603920630, 4474085805150211658090190066955902897001661633303260299025041221776891523378, 7848328793479881488968680696062292137496770320699466501151951135248413225123]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 22
cx = sel3s([e[66], e[67], e[68]], [9370960127159127445266474449258070389736162441470427007490084241211557822341, 14965609177224099035387154934147530900281499783229343066828915253839198476726, 10228455969106022490302521106014422994204231909208186519000062372321621002715, 329501376630941941063220737355314017862421104304435198239389326959464907258]);
cy = sel2([e[66], e[67]], [10405035931558887078762806053185283924863039263200495982754625705264574757491, 15502133231749593338314160389347860966662224717441686478526316588882854824409, 16159781620881884595657183508560936205420303661972673108699575582908291222745, 11627201183429653135859532750162240837549070563304757137644487859075461689878]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 23
cx = sel3s([e[69], e[70], e[71]], [9435538689621391149659891449161022313817917158768482063316123517911261629051, 20034929826130067090642639519998781717754864739607562909796887703087596572733, 2387945787036487514595261230908460627602020385539203589000341684029816345462, 14287010417915184144199881651073103018750205011354171060170509879133644433324]);
cy = sel2([e[69], e[70]], [3766822724536031967241092846229703633913210151222385593884505545907921188272, 15647190524611689022349999926088308537492889236313676989549224633916679679521, 12082040904926878889054967598271733538467180307938292871588544645957948546982, 18694076414086475523793644660947803814318698157437774233969783951279622080580]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 24
cx = sel3s([e[72], e[73], e[74]], [5859172856191457066677368896012140820864205253768332100482413148381377691822, 4109040705512320821322629424016219907769924434419769556997996401827477205364, 20898133598840700569835017147086534068242670333567622549169818027799138688520, 2562111968303466794360830608662119102867266861457203102917042145665851057610]);
cy = sel2([e[72], e[73]], [4836009713585714465496581912154882382453931120914721557804515434755336832208, 15143499611233432306382398214139440479742818510304232326049564749513747791130, 19356118393311375462052662305789820240618686111711161337705029468367145040988, 5688481852857742015073912476996667522213010914545901826896160233670889226775]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 25
cx = sel3s([e[75], e[76], e[77]], [4623242138639627730014370601705308411725596532862597538813607327046410321312, 20015154717710755506154819006635497782515667453025611627915382742560093423171, 3514612823502534944140986983282927838609295377065173960376131742886885892219, 20191997625806343264590099369325683216271615998169853765554784065039674586670]);
cy = sel2([e[75], e[76]], [6538526769564699401600543915225940144078494544354769810309083421131300518775, 9118555176257537603156148628736012723504563452923782011591078402032233615522, 12815558970989336318868652718709831589595442899079588636818966291960853991023, 7703616604462929360855592091876031952747180200478430464323567906544600168109]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 26
cx = sel3s([e[78], e[79], e[80]], [7426207409769264985012540642921370782277366662985635838803842004294008785185, 5999778250617485918891782298009709493035045140093544961901833503446031905913, 14130927440165985043471103750344848991689715792245153118451423398655300689873, 3796482870456559450471870663226834834712024906775762338643689176551263991246]);
cy = sel2([e[78], e[79]], [16458635168452867431186476181702908205218256620571557119181621733008943007186, 2408736441388526903801723805189252326923776373802231905332653169285504488507, 4539189593448662319023898529532785456602052593687554864880479361284144700884, 6490484418842862735983085938727562049587933870197049726191839108647357897041]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 27
cx = sel3s([e[81], e[82], e[83]], [9274793422641213328277630692090429447322754602554792362167389139799628719939, 18213562677024477140777501284013103092531757860081519011108723177266099803615, 5928914343334640962747136863911294731157726634392529232872962806197144988571, 17364692793332784962323580622297080260599290963212510860189969183095513710617]);
cy = sel2([e[81], e[82]], [2125001664000799929029867649528637137680130729147235858348667725168119291610, 15787194912569598784093233335743719308944830093009287397433562464152875584662, 17778173794489364127449950674919162836220066518510591114146982109869842663244, 18328553264273479562530008673792097214292102347103296244385349755449098608225]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 28
cx = sel3s([e[84], e[85], e[86]], [13710259114758767844337497139752382122951774216678047790125818858626546865590, 3343610505090632166881693615831990684789904804852523835888323130512752436557, 11550335352408668215051239093872906070657140182660747433535878335227749182418, 21793892863650948729507322696305982607072336532791041097212359516991274087980]);
cy = sel2([e[84], e[85]], [11846136982947366289908137269088548542970460276305965388699657623060915691485, 14439612735106182034303100596819001121085745615069593580210956482903072588413, 11243378354558219750264654469308879862376787156599458648274627817471028307109, 1416613801077957126034351583571856403044235139983509507026555602579721659100]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 29
cx = sel3s([e[87], e[88], e[89]], [16898533007964698268976570330413504736326631860509774315700399063143612293661, 19762411747110048388233897239023416141949331694011759548598869652948167421240, 11749964437081939283728905999710450041654325285452589389081577137553602604162, 16314155164640857713960417655857498051596153632474886680423284957133775223285]);
cy = sel2([e[87], e[88]], [19301014021919583977567348438857464752913991729661145830439339193394619822674, 4081042960569737826610743202667127127506276066439423960421657857551695871422, 14520831020919654323745478654766278220911435521609622705053803095115677276928, 10347543397607839527923790122253286529883327940351684415635401368115385858121]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 30
cx = sel3s([e[90], e[91], e[92]], [184222443282411811008485293978090987184574946550463281113036487016967683795, 4323925196392247451702039714921386345420807454721539995370304513020371659426, 2346825777983317939724845287942565740027799801885272779028341294742495881964, 3497425097320782814346947506403058330145264032565372769682636446824270312453]);
cy = sel2([e[90], e[91]], [13850322095814274715426304026104710047724256505475254494587134658322670671529, 11511819464672461161880080290029237185728360968222698390620899743097045452336, 8068296678016129536739401811575622149523917897086227154769231758295218255268, 10263809994502353117991909442849926729413925087877766198113026233378613424956]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 31
cx = sel3s([e[93], e[94], e[95]], [8995760760295995916308082490351740974639094331313720900267671545759667549796, 11019493928623991376174717464416885911906134873939034428175124701672655752839, 14017581177532816290320938368540191606560126820406006677979240977503063555845, 5992767544073504039822155308781253229334004182511050716159238341577147193720]);
cy = sel2([e[93], e[94]], [19514976680591593876219573359164805119998241765130948583982557052811782267484, 16839145730766072636625126513480100227916490562760284965681235183731245254947, 1021292692554672699619028273609664837317397089685876358558294458673381089032, 19705834660126914988160966717581159186486910721909298688364547098333399879621]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 32
cx = sel3s([e[96], e[97], e[98]], [2527638437523893015660301196665088766965588386392795314680197258969354623363, 1138471124880305373267488994599338604626881130398552196301155187554578496993, 18796280357765998280755689911684961342287093510307513491082157499389652187596, 17845424627755166990290252831103404879406229534320972756944316138691932923261]);
cy = sel2([e[96], e[97]], [19210721144465266426749734142673856566947869352583355496554030705736452071361, 14313930380744847001650971451811594041740544882894516063775993860263195402168, 21025107892840987725102949502655791789935181032924916608477285415225533245973, 3555509537083802658278452964512402851284368794121767087246797342866139363946]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 33
cx = sel3s([e[99], e[100], e[101]], [15846792621646742652974245065938230651829248095884295067743275618391603947137, 252268672903219503110064676037004166486655891926695090023400798499584132445, 19530459807361347014390846162868811023755147873522489974990781147946076957319, 6779173153401014221878658847395058091689669042378445736327791547741105926579]);
cy = sel2([e[99], e[100]], [13124560942345768357314581178595700674622208923899518932907915338485045148127, 19427900801187548763760894641856199686412861734645157290016060446141874396762, 10578265528433465376709803300626505953445780532420709942597293441366167803051, 2814357683688249343045032287308948679662030207205739212100871663137250686972]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 34
cx = sel3s([e[102], e[103], e[104]], [9161164860624082016500689976633279187120278305601384250238486553068325633742, 3594465641083658357640727503005755820863340547313408576898849399984296404007, 19745546026637204577602881915206827000693868119693662890799396502208696901732, 18116250696909523241042661347132525872828324429923244627289119813508105665938]);
cy = sel2([e[102], e[103]], [13685063021736046635507535227140671955502404587270095297507854657927533098685, 21481850865118949667886934355577641333398731968912180643307092533138863580900, 4539145198976864585367021826448478029652078179409326031693175016758410731544, 17461973876416788164599136875394849349337761082750935487057356278682772411162]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 35
cx = sel3s([e[105], e[106], e[107]], [13763732875937305178862849318112327966371606623409616602363024527079535241003, 7146728911382113235576196126361394323865045988036623175328726379662117800087, 13957018179677684863250069220406779871369347949049594304698838627334319400324, 2983130106134530061974606593769911479536904265326576922594002168086009867582]);
cy = sel2([e[105], e[106]], [15902927258231569893737955890837667742457214947649307818302524420399149241212, 5394027336566373776896911094388660738090625577337970061356832815458464701108, 5175259754491075858870829756483758144360263281431531384832593797283930411109, 14151565798137996208654994826049340981954317623288904943712618832232605861595]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 36
cx = sel3s([e[108], e[109], e[110]], [3511208839914156996602850728297722115315702089624058744395068873552707949103, 17785314838779826411805999953134869098297432649970533754606824062794244465005, 19568380235187862245567915799143793188430865272594403468605211965296271194922, 8968217637384711708369798047935037549991275897411766158377778716106218907618]);
cy = sel2([e[108], e[109]], [9113093883676083424918242033136578270322417571556449454840754893578163802387, 15195400406105586498427391734410887774383134313041084245786188708846588107061, 10391623490262978616498794103188417653962360594423044385370483010810406454393, 262198447430650388196958319338915798147458757989176286529479967365139093614]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 37
cx = sel3s([e[111], e[112], e[113]], [11522295231047132260758343744179190547608150890072723735296048871441325064339, 6417300850099046536319790332124930285535196168151466782463281196540309297983, 19137291956859275825926699344301804549568562573423342909926469403211747707345, 2774443339156228722046927543564067034026765236710736809480294993459012359549]);
cy = sel2([e[111], e[112]], [10997633658189180813501132314065688584832302881630691645920837501861598079973, 11230602434226993956802641296087754248529927465162671110571036062223097035285, 62131588140380451567557177282839666875193860544849125919004473298285110712, 10450442472445392653150568721579575112681026302736591474982185692600259786523]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 38
cx = sel3s([e[114], e[115], e[116]], [13408931465122001423751414891302829165042502658140645208130973182525808774770, 12919550455861565687920656314018840423444710872112059576718885637461594199393, 8902156077182438987081535936092318477847851529427670854791439040325983142815, 10551142139308027026174282362670932774470751296642556552082094389923387853839]);
cy = sel2([e[114], e[115]], [9267742985382681478817853200119409918969418222977519894367804134923874406267, 19027179442258820884726400809066833518658247567670360715860243154343698445860, 18038603127894002689531978859178109088479567097675385814346786297731217235404, 14150146649091182389991766732798336665028567292472735778013325601175132243538]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 39
cx = sel3s([e[117], e[118], e[119]], [6540890698262697218677202035403667770177820101154223149908034301445959517274, 435497241504544923461214042595209510655313029058197261483355541334388444061, 12972419969438465538309509757262343703702203355603454637962110103300326018994, 6669959829681253734882192282716498450739929798663147573799606668374867628160]);
cy = sel2([e[117], e[118]], [2642034845320222085946302229307945658183260378358994660373441270519802248925, 14736341083198246245608013213787697485596965707560872888430876049025049794937, 4329454540840640926293454385395213780440355759242417354895666807552226740059, 13390807756542084619965526671660454489274096296730210772303889980314835989796]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 40
cx = sel3s([e[120], e[121], e[122]], [3375661072576892623715175468380800047905893262660913295358697027074087217513, 5069202507845220698620539676049456933089654255996130713693017872693588276345, 307360032529211257870367390878851528397463530836715039216723323169226021440, 98081915276387897864111573201930613825497393423677224354881280134376446888]);
cy = sel2([e[120], e[121]], [8987539541637688797931012030256009083390767313291834963652110291129797020941, 17901947618091300697708370389296420066544823878914604900411880276648078042269, 10639219577401234864823685175468874052621402569992677814844863434253512890795, 13240331547980137691596357784155019878384406802888737259354896076218619627328]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 41
cx = sel3s([e[123], e[124], e[125]], [9662184175454991631880218147488300829920024817382740712599708905755708816803, 17771020629416708231961523003444615645037663660747267683766850455503462282265, 14494133870721701214401742677540032810309496543890589653927595534007509078658, 16561168866198605810694591274909829276030780262733890202994760647724957996711]);
cy = sel2([e[123], e[124]], [16632142917625566129622048663670437511136716491293457317746859226945397089536, 18400270017828347077622860778898029123047396355399577145984944065126581795849, 8353334605287102455944569500604056116678191817084945684486328539838325378046, 12147075225903504606648888869906750158496142784038841529413244301117587609138]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 42
cx = sel3s([e[126], e[127], e[128]], [20252038718269174556829574777069549258100538764143309785207012647062643184902, 19438750079062162172414919070069193686275943617816957878302458952613247286975, 2739523700389893370248547110285910821118647890992955640060929464309561828074, 18986163209792052202203221314221453057559857704913672555327882100075093616752]);
cy = sel2([e[126], e[127]], [1949203652074521007058676904301415827566224382778317340432698169556879788463, 4017921177690528677848183821427142247358574441895228503258380087834359360501, 10532220115833479369586881444322308530349489476356817032718755221032796227335, 20767633640647488765234831415684490207979213320475813611233243261000228414020]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 43
cx = sel3s([e[129], e[130], e[131]], [13929197264592281054662634434397205757522163835293158725199610804948038924930, 18983630674546465400919161958500748450652609469567091049588112148279229509416, 21298720061922244441608259922072286340766498728629540286898859613690667559954, 1255771444824172694387038994365972934222854858110644765629654650968093841237]);
cy = sel2([e[129], e[130]], [20928589942441069163400310179733448745002695258624629275677130484867901611592, 20945151313192869288039616217247173168964585800167278953053768079971885757820, 13394130995265898710013904122336137332320804034657805114241934415456940879520, 8345380486550648681305351465341710151021284756322349929795845243989999089313]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 44
cx = sel3s([e[132], e[133], e[134]], [20820962511183569148336349677594457306122370638840390080208640481304634109972, 21271204223521868772910817161761075423625575552213963956907846089587689594662, 10733658208915381791180435538254458430504966830986768682084274021501716755708, 3213872100717631866873070659546947812880485326599459130685149408092349854866]);
cy = sel2([e[132], e[133]], [18802948623154501291575097526503171935564067914914679326677986205652424463305, 18671196065143385675890877955428696189287618414074487330442057564568301653630, 17500512499632911097527623128158674292347613137609268450560746154383855656852, 10140717739675826292242942694935483711727546989965783109636404988746901047250]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 45
cx = sel3s([e[135], e[136], e[137]], [14908874845345243542374913242177817956756346686642792660468745914078612972964, 6494892024924675012540500602558430897039227451488331729419886431227425262471, 19660118982815103063271284609401904064050204952733042875484811495633642263876, 10404140614423982473417062438060653585074743419249328530274575800693260655367]);
cy = sel2([e[135], e[136]], [5109688569541183345813508363367270401129385455666732942384933494548859595681, 6488452587861781859966899732568514074249818909310744177483425914897141192195, 19759144330570995637436877834773866770106917696169828968224667729682932948543, 19372158643071160860924236286390794017939077735118276297478085704446653404487]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 46
cx = sel3s([e[138], e[139], e[140]], [1154476465911192808082307928347900064111325728833428891094393674593800812900, 6647319020085089760145868568636007917712315513936955502164154733998378717177, 12584569464684026880899751873241162942166450853083376779447501714905643756083, 14243280142991602029691394563175478833697759877979687578140951697024930901167]);
cy = sel2([e[138], e[139]], [6461899930945412323497751736369894620103555271239754245787726192367462376648, 11218209351589240489615573530963044202098579836550413344228327749253510456169, 20533060824796367399322624999408451192171574545415433951669661225068106752784, 11799997625790604641690313275280372066913716290701708574743226300595877165728]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 47
cx = sel3s([e[141], e[142], e[143]], [3106120971963814637086817095821216892657807437909030172048489357608690908664, 19983788499223635315597700897580134177379185544458724791602486120287361195709, 20011311503290782295958825256275853340402122848359336349363185226433870439371, 17061518479999755720537296647402074631690029621158571296727706119729187756044]);
cy = sel2([e[141], e[142]], [11655780578227604806047758025034240629153798954712964172707380870816316797993, 622054523287271568164593718522127794491026889292924398674394690726823527200, 16135285950085594062254918487673085571627312978983012587993350339361155816604, 16823182833153464340537049615227906529068252572342151311965980898836651237386]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 48
cx = sel3s([e[144], e[145], e[146]], [20374356410965803131887119977813187747682102078262988894186807366145009893312, 16140790886679277390055909624981354111468382311692868339667095804914180995816, 5269708933005858910719244518715051229221686961187992215177561544872857207052, 17003669964193566226265890987693478032205879390270724431641892912757008513023]);
cy = sel2([e[144], e[145]], [15298182760377768633156209223343487909782393543670382286190369588693664098885, 15694313374278606393252570906724471325000910752891934797182427274800382725179, 20211423855194801900153066955584657931131527051780164510917465106404910099513, 15455288363376670716062020330944532534047008363514636685826622499678373390425]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 49
cx = sel3s([e[147], e[148], e[149]], [14165004713755765453589527153323887724160944086658242248604905215519807263185, 301131970962481505862420187551701457358785403147894839379498410579773149817, 20703780629190814394908582715811669803434202446164042946560257906844612159868, 12367443634404793487462362639029662097550355799821945744713867599113535990920]);
cy = sel2([e[147], e[148]], [20401715072789557220769413113920881979690352159560582443280493351937640089943, 9512744351810164617160144481900582699060463555523641782334998030336637339295, 19997026788203221539856525472799656962300551306251956395441891331721763269878, 4420107516401930587358239495168429945976230331917756712920657983670672632753]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 50
cx = sel3s([e[150], e[151], e[152]], [8103748105126096403620617531109165346111017883414253359146860083465308290054, 14803748343013980101691104453457628404765420707022107332787520877316491921572, 6553189032217952509828188229822974795796651131494012230703062173727191718256, 14488140647832162063035434131927730449663617866962750748399561354722976225897]);
cy = sel2([e[150], e[151]], [6900602880532330473224374524196761198151861405485326291615150754345009304151, 1513115647408875522957756488493462370777248725072062752756727843920832160085, 14896301840535712091808125164986771300932651268478608922083726618785610993431, 18048817115801653510192862998462822947761670069362294686696577131702147477504]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 51
cx = sel3s([e[153], e[154], e[155]], [382543238316875203894587902417533689378617036331411163099475938996384971274, 9619454944964330535387495829359535093743583319913348616872361595592109685167, 6081261874729821958303230238004699407225832699063899155741932401034312247576, 3156137884201329913786702605630625537320273632812696416791152392474314037759]);
cy = sel2([e[153], e[154]], [4793004393185972052681267640894832507973895495734257655931836941627180322533, 12524126851245821931846984936446041288760976334671736634358685272033969216980, 6277340058786227516467028124755004985063566609742747175031180490042372405740, 6981569030046806591634476164525159834865090256544287529201527685109358245562]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 52
cx = sel3s([e[156], e[157], e[158]], [7242980429824960501440666232145028986161691674990466362832703971174936796830, 8045674190780012690331364750465564303458553754280502177743436741257674712579, 11260599103741407968666669605286104777635431193927929500939820855376897097946, 18466264932289657017935069178634633780361979903681010210726608765753592098197]);
cy = sel2([e[156], e[157]], [2313823382391584526084833833122921512331314230217820828722208559851046887792, 10089801374498501989652677350203014944991951797848003015280234323125565001040, 17328843896403558624774477961071623822106890748911687259696765820336743222251, 9096128104648798569037169791537313868030583174665566146242611146033775655076]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 53
cx = sel3s([e[159], e[160], e[161]], [14129501557712467097681133312480956681237794589418881140932742431414452181802, 14215253979300894109266393937905007744674886266134853669970409340633353105422, 5101954416353969027375336730301151965881345391948426977373049227857281866232, 14576353231486654843487902119173617652532372118230138091256904812874365465828]);
cy = sel2([e[159], e[160]], [8967890713970048745032869372462848543847652746940083058618452105243173038725, 6265601060440963621915827684472693851147234848878380918293598569151688236174, 640827344679117882936589383352750227742240703205324868948399729377934123492, 9724475542168570127797711494687143027178927970205326782155651202256929792882]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 54
cx = sel3s([e[162], e[163], e[164]], [5456157947126010471455582105823966618048439614862840203794276433144936442303, 21043218890179638595653930578748044093798652379401035786184926212259053133276, 1927155268257451951778867733460386031395807546286255979317875653435797662494, 2742904689169248143495331827109449907113748836918731412006506067439664106654]);
cy = sel2([e[162], e[163]], [9440520397717291873292501513394144011971438675685104804031688857727475979708, 4417998885632129975756353073742958617120204855631898102096412742879398656621, 21718244289007192530526626848367390261419399428442075984244560471039861817138, 8877177915758141474927139565405950662745390581859900899551672907102924557478]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 55
cx = sel3s([e[165], e[166], e[167]], [14850732473677774396477975866215714018387310838284937771253941847508860390570, 15346251439912975799100173523179670100616030950715800206631108275859894555954, 9806744113621004413976521475016417033548532640900224199389230684453784278689, 21096603979133316753091339975348990230540836494614368335651248862844085270520]);
cy = sel2([e[165], e[166]], [11812452402407343928752680921354215607515699690942611270817873638995622443255, 6279013985783386608484242724725362666241553499782119548714289191679033556648, 19001277736410456807324578202368992701796359861619482537978016830870842626762, 14081519926521914451511625869848591232696520686473918498999632052868953710854]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 56
cx = sel3s([e[168], e[169], e[170]], [13157890071808158704354468737847471048810392369152727364639634059504126884874, 8008722424616547903294828680672771630855086822683412918399539174241338981774, 18594694810411494426945160098830123105355833500416479749049639533195702072502, 3003039638546974941710738006242011804553647552380262745534233703293489168909]);
cy = sel2([e[168], e[169]], [893279927671356626449601197530638356692800493991878277093322197544680454846, 13710236865890222581902901564951693313216932700203676104342205227571583021557, 11991140728188265308988894689292592177761583244141205754043533415013439187396, 7408159576060936012801497750876509797959683640624248586584358220473720101773]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 57
cx = sel3s([e[171], e[172], e[173]], [20379496501734200220097501155104742700678033944324898621914782326376426827694, 5628902661740155176800052287728775683561775403751721906542502141173662773805, 6649334930850298644282280075473454376493217119135753313843458230202317946465, 13953386616146853105384995231337773651826685901371822028427880819484312577968]);
cy = sel2([e[171], e[172]], [6312536910770269621417292581781438152243262819530627194840110225345012746549, 6128625960467547051042766267966540761259574034224991328868848127157477007514, 2178504154437332931470309748598630309367590073987406533802402874933913898875, 10049120191768569519993419401578117655266529530568527176008678950298967775522]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 58
cx = sel3s([e[174], e[175], e[176]], [14193197030749382932133736734505537242924559995077781886176225169837220402133, 2565010016572214675455233006763278152319972391059007175692722972374012019501, 20022269140157840221511080273245661956116845958170472382643581298431129105222, 15951592620529204477279907750991493798200861674998832536410750610279414881478]);
cy = sel2([e[174], e[175]], [10015961841973388881391587018151977950817576225746650865142918877894543270446, 10962609190943341745700082387389939598903593214578149618076217369020441344245, 10875728650787073188338824979727792178460025858689164586811311106195554874546, 8704250736813220528338393230481759654328677814076110220308209376595986509914]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 59
cx = sel3s([e[177], e[178], e[179]], [21185904177969045625821216347084191287459806531017721293624058180265336503811, 1250611256248923800378335492392268625608584743125298517147184362502718557754, 4732901842829850758626640836087921620095030893254064254821493648172485065995, 4686012912505407137434711885457531064310116778761775095814150050521297721079]);
cy = sel2([e[177], e[178]], [21681922300753515822840018285496181872470481450737464910861242457369823926925, 8250546098596619229605270054781796306579374634169772718113961166155976799791, 19064654253935902908485961089200674782438523882800790190859631804189001729500, 7893084863238812828005589178028293328994403260619345443806395973318698162130]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 60
cx = sel3s([e[180], e[181], e[182]], [14071560871369419892033259843192185467358801846474749773427241883409830032328, 9559459046618636497241065316366978002044190960713451216793292122894012900863, 13031319565545666906249801044337083380860313201803429372439840529717343742035, 20069400641162643493898109922008601219601618686364720341639616051841829074334]);
cy = sel2([e[180], e[181]], [8710777380190521326883551341251426052007249230093350101154473409247609882825, 10439377650670164179707163339178975058403688089785136107598148495986084488509, 20130072726000251358667317961033491205160472226244307309389477611437739154303, 17216059825244204015919013637129845877195519789582013765405196142334767977705]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 61
cx = sel3s([e[183], e[184], e[185]], [20777314589605673759170070653370407645867665889025835324139659856710113131826, 17380793433135473426803899659206730936771330488910864786997506181753180852018, 9135535394443552083655851762956576299400389583070951313661035134759057889658, 19259342468126216922767538099314197508403261200862162612026099962268769453780]);
cy = sel2([e[183], e[184]], [2644721599238941245572401477946144870669550581359063534170381908963477379532, 12369176861935895868206428376006904712013007036288222495431735574326142454609, 17367574625533031619575225680253098966157776114681359698904430545328078639283, 21794479452176520273231597892096817659539111123775968164861961429589103329517]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 62
cx = sel3s([e[186], e[187], e[188]], [11749872627669176692285695179399857264465143297451429569602068921530882657945, 31939593233430950996158270398727464286178387866161404769182205304632811436, 6016890150518491477122345305716423891405612103278736006824977752295838970965, 10857254852618093631105790010825256882158099527623146563961929227148379359444]);
cy = sel2([e[186], e[187]], [2495745987765795949478491016197984302943511277003077751830848242972604164102, 6997914616631605853238336322733192620418492595988404136191499921296408710465, 6173428954671571373132804754825927617043378457799815000168451967196664752847, 9007836187082518685036356739793187792845982511088020304887245789556567564055]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 63
cx = sel3s([e[189], e[190], e[191]], [5139361255050232661773452561726452928115803730344567411456642256556217045338, 18849283619433745348738480276785423370734769795033289874458118507070173353564, 8448578350964247311518616492977206693278225803594287158372550008714482924618, 9689086950770336907190180706142608582993499523814136266854852845122214734392]);
cy = sel2([e[189], e[190]], [14036051510959474100046039284978060652197630794277473374328558492372137493500, 16611708132761924749528167866816090876717761056993928787802780141779996313373, 830643686092782069152588625317289527987176650776268015346372712951408738404, 7124577892782407025863252010240336830171667706358033009166413008136074540762]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 64
cx = sel3s([e[192], e[193], e[194]], [7037199118537155369331275916815326054696699996573020862644806346516390510132, 15801832773874273151484928140234822912161499004629735400320792200594998558674, 20529919447890597649764739102616587236240564012012882223198985848792346137419, 15587579342628673804059001440002406839596944474602936992474297171186661645909]);
cy = sel2([e[192], e[193]], [13107688056462500445700480209995877016295689081542565992250464593152667593220, 2950999836230463387014662253708191376901146777669866592618407913815214817829, 4910645882425237270468350930391794068554002250789220952036477599584216368730, 3842197005807929553563656299566067039385580918555124491435963737335985608367]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 65
cx = sel3s([e[195], e[196], e[197]], [5946112335249256697077095359378565725733629742750694340878812663903909175901, 19030634249222736450152769682445487635301904450722490014396919999971262563725, 20272077332559936653726679368964023857291782018546895109417787179027229259529, 4325773325239231432990045180370600024086140077952119719002873860984820794777]);
cy = sel2([e[195], e[196]], [7559787099338642680034184654424868894988928943730034769673486129058256478240, 14955054800505659097184643689663447282484820948805633199847088945313706647256, 20527315092050743721874398127103128550881291654522271023332206474058940158292, 9254615232744118309709861811378827051213745889996697483998530345751148041402]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 66
cx = sel3s([e[198], e[199], e[200]], [41373522534463253583709483090344938032869463670116114182911184041610044395, 123058269904779894306385100149700584700988943576532400555257363214064615908, 2188259327903131136942811179577591848088244960706164332041753317001971084806, 5677272600001855408525885379297081872841669910685379249005421935936405438326]);
cy = sel2([e[198], e[199]], [1812970364913777725848745565574644898635129603904027984751613694625700239455, 6325479481133126048154398075474627535983053143312386360869927669212098083218, 13018920334214076613442336156617958094802950850259563883918734414290288034687, 11007863126994999194753256186448493793850907406765917922947224071691321773988]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 67
cx = sel3s([e[201], e[202], e[203]], [19366353265983664793480214800587120487923062015491759603977854723148315579274, 13009712389497066149642205706505053720391552889715847781477674095579012684216, 7540090586243428109828867879678893096981460680323209865296583411528024312326, 16312880719251887899651071843693753472207446322138586240016038563189666076704]);
cy = sel2([e[201], e[202]], [10425762558101863677692090103799691698591185440858290129753641015260969124568, 19889759528114345474077603906066211135049113446169104039752988610769598108616, 10189577411425365730046714422122931951193107064366232919940491025624263274830, 19402847860324611226251435664012558569374211845205502575728141649693622181131]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 68
cx = sel3s([e[204], e[205], e[206]], [15647575844595805283124278572298605369081553302159286302039104118434564547757, 11119588224460846619648329471078205852940427394545403397495758589586019867123, 11531502595396972280500527673404404955773795456604503116176223280757803701142, 8880302652736630728773712083983401143315564427649676162399333300472018402820]);
cy = sel2([e[204], e[205]], [18121989769429113110431033241130632527148185431169035091659247063715924437727, 20873727571773157361636727287434618496229040659202161464546752313173048350714, 20691117161323169072636575178583071560333787206766658873639451682743014282486, 8341316767034979343476640425183870254531797329971610276320314018660072501097]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 69
cx = sel3s([e[207], e[208], e[209]], [15099126396506559307312697471585164108461593918632286769972271267945539855806, 19719992822745709208744805037389314455441129806628318848823336999297717461102, 2498623947360180463813005839687911187525292314091943320262937967401409761873, 6773513521666107580427042608663114222160509705880285715315137855519926605076]);
cy = sel2([e[207], e[208]], [11185464183896587792324099270269738719144599552792757002841466742562118002961, 17962378754832909648632213279341274522205662106198070463591287770511029247082, 9572883626752796327156744085207279145562604122052196885537416403686418306743, 849739335033117039567862203783008236118271414428303942526044722712316390134]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 70
cx = sel3s([e[210], e[211], e[212]], [5586425841805464495367763159434170408121119147683098906675715851224959199555, 2275887592294698256371035540589451793263643729528648494997423042939590025265, 21623018362589173579186020601617142922337607155324626054728009524185014872882, 6470935377837087985284657580709150204914393986124872780110914178120147824883]);
cy = sel2([e[210], e[211]], [18977748529759410811480134751116373952642146764796083016667926272252310801539, 15415054474257926323577643558627142211566179025425425674112343915385225979379, 10178696720359974033063364767044087765079200964723755314869211737985682962880, 2751262919149939488788372835165540688204591943865442185170575019042791606144]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 71
cx = sel3s([e[213], e[214], e[215]], [8067396068830332270789178613335432253659758303711969642714931687060160381303, 8639011650360344590794984878540401640139910601923862912593792315052343319076, 11233915498048422123675368878285943174009257862418242010192825609765986035356, 14474288438243449444797392475230229280689019808482654245523987676777400402951]);
cy = sel2([e[213], e[214]], [1109389204114118726338211511183391561882818362713716952828416479757048480713, 20658495580821728113676289889282525822016081521980495256710356417074439523320, 5734616557338566574377893898300784804059511397655030429323489999855673254133, 7694030151585859685333610687574701561418848021817379115721565206849330185976]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 72
cx = sel3s([e[216], e[217], e[218]], [14694205333290671963708923368506587408024223912051732033761240288927263651380, 16846840700984603406007084554481852964137248522784508429412010549513323188912, 13176399412773372610094105377631574988462669519590170596472033646615482615262, 2687848140625094867763341291336975245615611233615607599401834736964978577349]);
cy = sel2([e[216], e[217]], [9656049051507081163863869851380474393220762381365090138663873299937439711626, 16257833452680722743254377629669121273261457821544261762335781528496650481193, 6465537052899418297534883094198381748729828452125250541158965933076691478294, 709697610986733714785106299677092114124154955937070541190663241187641683175]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 73
cx = sel3s([e[219], e[220], e[221]], [12368397247649882906953915991250714931614715588424094368585746160811998953306, 18782888042679815293214947449937714827609414183597755427793821090364126288476, 14980906670860851104998617553690749074165805207013703141953243482569349981523, 6579728809126224271038924161669519472291072114357057900231021883849035745958]);
cy = sel2([e[219], e[220]], [813793955589589118694666569995091571992486583635127942664119751723536369919, 7944299604444967298799338830762202580774561040186193713045849824532426689590, 10002642178009570948907228870686621440930898426698423035982221525801621370935, 8479337223317874954343670583381865510386888037444628897905418707487375421325]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 74
cx = sel3s([e[222], e[223], e[224]], [7187732531650016705045248947412886871494880941757180032721434029527647591174, 21429737681997573327768382790700665701419541321736653106996131182050077581533, 11836369351087123833634897021408898134248512107687639835461193259880629295891, 19132784475506243814038464623366364810380933540097619300595341694560215897043]);
cy = sel2([e[222], e[223]], [7505964932526905326140236282846132917485872002527800757209057356562826370965, 7446191000078603169082551991705097881255381261806164450828019975914186121730, 20501368217451607884813098738754813918145802982055856468691458112065708320700, 12111360534733555932929570216465933882611889545473508372687771008732927246750]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 75
cx = sel3s([e[225], e[226], e[227]], [11880592453253678945312808709337779570677968939895786745513483795196121148239, 15885465855717299709344092447684246292163545547216436459368792952573638150871, 15785265541005027154032372858808930773051366971093462129449868653918773012805, 18569197812514885943202170611076608358219751234067371040250790526837986392838]);
cy = sel2([e[225], e[226]], [19319714983097503154896952315362236888483358620825042533226116711980128027594, 16203396727641772481371087324762669694595077074099718953937599120235089562441, 8069072007055358551280258194912706575285364270109077890462380604843344248137, 14879918508369225877688675007526587407926006842700210091106836056129459129297]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 76
cx = sel3s([e[228], e[229], e[230]], [4665897628623235203637312232323957679483103295583092141578808282040205079719, 13624944208440724520944284383225072602905876122550187793344788447894380752405, 13240065107073736104958720757918020581159288509346627802839384665867212601652, 5404872141819776433203748684385984691445987755176034496638153799038857512389]);
cy = sel2([e[228], e[229]], [20713846021060085908071105513304556412817630308151607438714049866357354550752, 12308156363070414998141304956459569678321247441462175945058420898750569812289, 7869135919638822130359819523186642202243136255410646018113662355856102696554, 18106721900555088660857020092432838491684499647468676099930405315728768226404]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 77
cx = sel3s([e[231], e[232], e[233]], [18212889377782903846034117170355855193339291343619773736161614903123505780500, 5724371935927035469891307360583032289870105083635885948626519084327837492412, 15018564556029978781532805643572668082137657619876811702006326742091833640503, 1980690392504623526106436839420486135508948878537486163191798777558809427629]);
cy = sel2([e[231], e[232]], [14150007145691261709583376556777715716099818143565185837820917588114159379297, 20022624235079706615759218203483775626475427851084411515081825296526003331089, 3653600812499303949236693031235500821149221426419723829534939359247593779698, 17687818220966506140783793822520601258809092691114698078370817997514472088683]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 78
cx = sel3s([e[234], e[235], e[236]], [20014362392122060372382978901186124374461219393111624832280409989286374019151, 7678149165067745993890478281145655203076154350573466295728882151032664933813, 3225698435546178867794794576435022149554488042976954865856749306115721077662, 11309031064526492555710928277445241789558140050876975815061803061421298770441]);
cy = sel2([e[234], e[235]], [3781524301363795687584984812832316590367643113392401377547409393858835211208, 14954378542264966404669454369751236758988379152056658083888298000396867621936, 1762346050163239223923110798598502612894079706374187891044283390513959164382, 4511820337785812086858556857918524260240820667203320876468844848816354037596]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 79
cx = sel3s([e[237], e[238], e[239]], [9734499467834650890192498500298459962067559704398257089549121433441674087115, 5215135617552133686060655322881340267001697536486897440412599806944209294580, 4188240743485809003397687109987123955188618656835900004447532212211334022150, 10646753846009034357734238656245532993332944314059322522045789305478499710981]);
cy = sel2([e[237], e[238]], [4354361275489184569727883669567924050940590772506719250562939951242102459556, 11812679101253609883065116716426172392592451529279171373836703114919477018303, 15938685241828674681356945591247179905945286496762161102822537588243702016335, 2396399767043799129388585002615296373717040489521252489057941017313192676808]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 80
cx = sel3s([e[240], e[241], e[242]], [9547054830379311239093093214427099367592481292385809745992166194109928893132, 15809211758984123203744250589992081971737344928666499432318524828207451637502, 2317605133926452505125489082200124096354438531853199813212363802981648616781, 11720218057191867199121604823871387192503455956722025424220873115151171617846]);
cy = sel2([e[240], e[241]], [13627319622459471863286677434492810110443625239619395014230589374758547978269, 1429116229161069264517866355097922507661063351137334983223517731193665190730, 8760550298269703331457356635709373772631633074463698514870757469189354319951, 1695059580774200437965405056230849147697820569205516838038543601601027611172]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 81
cx = sel3s([e[243], e[244], e[245]], [5462734684060346793723051717116621327144354637585189012464556861789633254735, 1574368603481037100592052661337337694471748163849816976465511323905498090898, 21017620690824743015216528248522045704369427405753453300912995325024062710748, 335774257251677761852834523904277348100779994383726453798657085528043830396]);
cy = sel2([e[243], e[244]], [19956048369873968081515874523485925798105246605761695905870795560621002747577, 9838187823381646970305000918713399614038197140004128824046441620722100628627, 9761598443789947780667845618272433395258577614354457312915153694570906468084, 5678382193061301565104967410106463714669588791192144419019555111526838349597]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 82
cx = sel3s([e[246], e[247], e[248]], [14120934246971429747829618071104732571014495017644755746350410437296386191831, 6321525285327330824512104449106606616844709114576208465479970358050873874349, 9828948304711234867338016094087396323909457869737239406325931677882463208355, 18078003119304519959309175940845224181126936983821549690560235900824217790962]);
cy = sel2([e[246], e[247]], [20946993100078048703890437478651577253995893117657499778417778292965813281806, 14356404021232332461217625395600664517715960389258731685389867303545696108853, 2810577432005044954032138045179699447584646279814848461184496089430514835598, 8767040452903340993130881597424027588451974218686780194782289690479045090015]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 83
cx = sel3s([e[249], e[250], e[251]], [10074124480658003038181060843544012751655263682971006047574974839001332519369, 12077899488247602319223956898393373607365192976733626340271805296106145121355, 16135938726601100366620437452815649119119591825429317780601932003124015669028, 8179818941824323394614877573129531443686047058703515433852568295536575458823]);
cy = sel2([e[249], e[250]], [6742523042997173838799423244280133352249230789995302906545025471831316165384, 20571270140927253125417728386763981919687051926731085366043566448009069227191, 923263495309221023264076470401516657594260797987069910555955234338720881738, 10846387476002903807347429282866412191160400241233297902208546470305682775632]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 84
cx = sel3s([e[252], e[253], e[254]], [9734317150772506967195863825775613184177780587009303743393397724706924797808, 11208201130011695436334652728584169313726840614571295516236997046457697153324, 1222680486642983364052833343811429934453835860106899436901212790725638894713, 12019238493894483056724448289009076436822742112482573063847552596048227585627]);
cy = sel2([e[252], e[253]], [21086552119896541186107689532205383551960199801453516689016972250104900583432, 3056767815025727154134820681013380076250249612276183869180162238277626532027, 8232281317297626211055636489579107493658454229617058760791605403582002142140, 14549672514437654184453326941604694948116368249587796119338038904533837120165]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 85
cx = sel3s([e[255], e[256], e[257]], [19897146034704593618377175099239959996606643851373776355482440566659528393713, 13567220274372260527197800746127305934893509881083589343644604005840555405371, 19175080795372179131749429828665039169211560827471558543841205575231867635965, 6917449549804522032498038894724900459329834531091410689621076525743611296938]);
cy = sel2([e[255], e[256]], [12223657826278264815494051932052421695129917274617530304443478482578919678308, 8295548603728936503708692859047908287111164162226375098145740427985958712611, 6607229719664137890140258196376647042900642854569636028419328459816951119658, 14110421155257010376968111292134385106023449978845823063864491477811661996253]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 86
cx = sel3s([e[258], e[259], e[260]], [8185677100333640041421355126903921619342273914070568426300075868606141405021, 1670466886055998857358105826250955310011203741639197041742892893805477021056, 671638389102335040808130453738616724135371178235871000115155863725237535561, 15155007602444057841308084879571465766457754342497255444459746080732112337898]);
cy = sel2([e[258], e[259]], [5730721122742653576294802609542803235749403433458024692842251665338778112357, 14898703166129675283863893661050084311561656604196737234704191900969087474133, 2459074141813559460216507737311533957327810551114696579502401763839835381335, 15516107503085209346875467061340145906150528515154791297494671889511125291207]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 87
cx = sel3s([e[261], e[262], e[263]], [13654034957145907815962106285631017905892861670471883127206658577251723739165, 8633158844589460452837721754446206625865140330878411953122575379370751622485, 10232722293127899126024059808155635562748968165573438955077544464410325913567, 15328263964181874734867171882863588382257876665732200627067485961683406281267]);
cy = sel2([e[261], e[262]], [14648234277430895067547661111448501238234630914838612427562971477472564218927, 12394752068682518494797840832073763890437175762631359486643184011399642941695, 19427382571659868487644833684469199967640111942906298364811415181281091481616, 182598521940883711045871251162735110551301299145061787687905605212153955957]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 88
cx = sel3s([e[264], e[265], e[266]], [10625366736090949097208784405733508126867531010210504034282606844498242195460, 5745457912443473561064508106222759378152708028067817946740487826967842596074, 19720099885004155494384241598041924024056522066497340576395346816817691557959, 4411557748754390593675263772383003703921572549170163035845149756207936580167]);
cy = sel2([e[264], e[265]], [14732913015624058203205922728424826465278063568996784510238321594483738024116, 8539999814473505400128567752428776172019356440581684960088711125461388816752, 8671134805346361443739204337860301475415660510460401138135319415884938499794, 12889649495366374604591900250806268552879620119403975808021738180701264567775]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 89
cx = sel3s([e[267], e[268], e[269]], [8424620995080153959855099087384460880708718787657472234234125992142104413784, 1213413054380708818479960383614577938132447492306231448400493113424770669073, 17993616645286674150803280096391639271887381916203322164869533675674274690369, 153030618728554031479557843767027262505356544554897273649773418701874030937]);
cy = sel2([e[267], e[268]], [8774350273413061850499929377371854983526435316805379820854063460345613579740, 160874859222003480689240665151063301233791348742268400199413950144629148606, 3864981636983763871420661536128329698816776138190284810024785475130342429509, 8927799801878514388025533121285392339945739901708290822291826043102309328947]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 90
cx = sel3s([e[270], e[271], e[272]], [8559837035180670877234803295116293964077309001575836599087921933374799946149, 18335809791652365585369283816437201104065890639760635850904865621132150615442, 20223042693949477624057496950714682763488956308852238106089638364544757819336, 956531986282862630457073126978994765430652506058410664783115436243377137130]);
cy = sel2([e[270], e[271]], [839500690449928047855071514156387100713350925422279056462945330783580827563, 16644736196961833445797352798716804869773621626799896168771841453493474463773, 604545836161644183235683876796430911898168138926947606928620724963455977159, 13372011982201734306725124438714782615028067496534473713140957917136368058903]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 91
cx = sel3s([e[273], e[274], e[275]], [2094128027031828157560092686172909842260483168819281235210539106189673022187, 14831470033363035728579660771199958641838096197597230010879786959469055433282, 14580113677826055589909107333827815551732916495147612562237413782243389891044, 21457439024195964947733246659608329461028391228550531897929776149059108022400]);
cy = sel2([e[273], e[274]], [11349460624897126395359735030876451695289908168621129531254166231469594999395, 19428708736392770387243553726555356520800900418277262898221664159221843559913, 4432119977004888069457445133143529511285856348699582219607694824086497898807, 9160542608356323143471297830883618199584611885676024272763585312451903134897]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 92
cx = sel3s([e[276], e[277], e[278]], [4354759259287077683606602421630609654573093874872166313972356669642414450557, 13648951383939395268518611670175324834705441295145081802011558222046663990635, 14109063296906889436525684297777423342039664400074253643711178181120772454442, 7920829805332901764517739207944367186855755092397343817260945923718690867274]);
cy = sel2([e[276], e[277]], [215179997319049227050677351252505122489806707992988193421803248841509506088, 15514289571504865101354424086151224801481680739860239328031576438563705370521, 5904618612526890474103927634405504783798865056645457180704237978103781216311, 5748211772814574948909294216861178264766343013494657271260147929020820008781]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 93
cx = sel3s([e[279], e[280], e[281]], [8507753630181199902479216321724505843375506218865451254864654248120523505482, 9450124212352501425016224885075456626937137054710829941179274211424392402188, 14617760695968479875555170000896560124384001439628509056518085157675385430999, 11259792651191057957240332532512267993084988584437199185342993378682410436972]);
cy = sel2([e[279], e[280]], [10815868200773974736475276546832667321164179489094422703987813447328543028788, 270750089909256057588643640569447562301277634245971255743235422454022028456, 12525264811662854133497240150104162834870195408235601736200987821770575683753, 21492322023082787855062324449039977497952909569982074113097211015628539637105]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 94
cx = sel3s([e[282], e[283], e[284]], [13109291774440010508838814834344208104350382843329321595606001193219335478061, 18178081082215000330236621415683992037792438414607902561151998975591610672159, 1825689425393769600328701494994687539687903068590739461592021486333291661266, 7793684058500310840246186772109776829776364159558184911962167538064855177290]);
cy = sel2([e[282], e[283]], [12538966751785809241486764416198217361134417700423840996157483469862141526006, 18918692038570377322252840249784989027502652471358614978414943590808682898821, 10739840318098234656669579810873413661071494114926975536918927404574756289141, 19177195314890990393062332918745346394029203576215723513167013054282705104509]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 95
cx = sel3s([e[285], e[286], e[287]], [10225920463059329189289679689043403756461771898061631555012236633674500607894, 19821058226025589223575559712382894896410588163797548720897159700660021786692, 4342530929634070742874132949165242936564090903607131574088848141363806195244, 5402483411262228419126012059406829285695506472234034454332016959299908934815]);
cy = sel2([e[285], e[286]], [14845268720181506270843668435047795143673881800644972711347963164805203292028, 13672974733920510644893233723674603797496603310630434825704649796138313401676, 6411707949262855152252009198588056473458716851460397006471717726058983234993, 18779680229580121519443328584313676056219616039194596697158403462222387132381]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 96
cx = sel3s([e[288], e[289], e[290]], [4836760236524137019788853323648085337078365119204570171912328851849081302469, 17868028324749251162769441309905628927317218753130618155651317995445082462075, 1772933343466453031175704703581215603932939906355841484695391914536709138761, 3546600638749568273439745161679319484611182076185127936908592367054940973889]);
cy = sel2([e[288], e[289]], [15727462261854339392836033936665994570356817309630572739663218192786419709049, 1337461376408438722980356088847283448049292537148264126525086899131501823829, 12238707625348281750296588592788256417660177170554983893114345282873428793086, 15525437884516977515442248737754366741726151193578138245479811700230576818338]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 97
cx = sel3s([e[291], e[292], e[293]], [20126221763126240993614454578144859888701958472483256034667342833856637405284, 19699064573618103786080175406330154847584332570598813466503995653274429215656, 5989506922601319310850294681562133253116809072854033597983216925515271522735, 1000911579713616921402553874631906432389325985380989857769833587362794312630]);
cy = sel2([e[291], e[292]], [20063374408209966489810045113711694748195105838875731221209079272072900704065, 9194215440981146522641296536570335847038564333573070389731736048602585014353, 9856108459841119062384164372572927792749846793172495377480072007040372623532, 16456996545907573633695460898581306270452076960241899452978065386508672788709]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 98
cx = sel3s([e[294], e[295], e[296]], [335301756618437339439144029360964383534478515390448989496515998200065120560, 8900295787747118853873347685755889791679080209434225159052383890249026687118, 7128354610803275364524320321498051406687079176221803083268519268078181474486, 10587524605383993790235166395264599817111999691721750015186077104713345396025]);
cy = sel2([e[294], e[295]], [5048381480643837407413881593434054866090196361251156389103862466064034755870, 5633507321470690754598569732643608340435754341640194463936636395149026354734, 14155759183302230320588700447409830028824433982845500795956824041195173925296, 8029144329154622500871732803176023714578210937344495829905950083327660868243]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 99
cx = sel3s([e[297], e[298], e[299]], [4778598962832696072676642978625204359871247189399816084941520023705687820799, 1041656446764385248839445285580789894072064765593570151992974139621577464190, 16604772736533716135897718386428759521995904068172209060160905451073360508438, 5434449975739162120230503825057718004673241312353068784008427484008820677975]);
cy = sel2([e[297], e[298]], [6056883361340614567315212379835078890341975776819628834401238537031161511515, 12948572080347797369632667255105735306309789288527345335385584655912071062991, 2047203431451992701474247296709372094572802843600017662927813418631212656090, 4132565694324682855622172238297326586214736771195057409015171400249163749388]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 100
cx = sel3s([e[300], e[301], e[302]], [6916961985409927380628327393774423923434707859806165446564471158322143896430, 5992074540412063352415311056228455935293166060283849428112990098777744329018, 15928943908823412922424046027263578805013830577468518797177611363337136608209, 9165805262654590321870254579036281540959358923531526687992873621654142568029]);
cy = sel2([e[300], e[301]], [19113997592137471372275504986229466743101683336744251847362311356790431849943, 14004712182695079610522706143578502649621084194457654873685315715331271860709, 19337382334092833222650792928980596008310896977712987991984497026496963328127, 19598147310295874176650103171586127283815601834965516057565002042355878900904]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 101
cx = sel3s([e[303], e[304], e[305]], [10948634109523663410073892096301229908363974454242026292710198013874268733721, 15429431087099938206375989354827088309373134102432374989679474148007045226404, 15424933350139202912640857850279200342934439164947473620816895024212952340734, 7249326591094430300092421476233168005480477057146500206388167575638063334006]);
cy = sel2([e[303], e[304]], [13978844239437491612582517692269818179489578402023377256168376965218369369939, 2030861900932117628118671150363276958527364035939087076359289004302891739342, 15817916211331592751911789779171300716227893840209480318007078572691072662437, 11627409307299027242340485688430280907603952564355973323102745520536413654480]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 102
cx = sel3s([e[306], e[307], e[308]], [18995578047969205917336954191535061050094635635378379108624715348396977983189, 4225372875497776800681698864198574622710499387413704002947025943614195612470, 17351437921298308953512714184518159189123423974926314714485788395814969849744, 8648037604000808882689040136601171409077000943524268908332163815927078223586]);
cy = sel2([e[306], e[307]], [13847262887662907650775044616657488013627923118617883909535158774246706595453, 16327475809001511779800793713087994795688106377254965385366798254360171531485, 9662682437808722890180813130657795806130406684446667889065062080930078837985, 2502962306844881519115529360019706751646009100590601561262014681428188719652]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 103
cx = sel3s([e[309], e[310], e[311]], [15920090333582846150341817050024564335649064112537068561935372152494077145209, 5605643430930274732542971456995927736808851585930096579266761796229766916419, 16417626123069839752924241752177228747744623168825833393208640134299321885615, 10047503027147056454952493773282171263110464519924564641292405110762258997532]);
cy = sel2([e[309], e[310]], [17200096279975283058225939790642290750952306062383335630123644381672038262866, 9789126042032908977600199303915152601153926597218655498907321898754260478045, 8000890408406693601499028261723138327296400099255905955307073434675924377491, 4588804177243916206243160261751431868697632792491002746485364561078105548339]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 104
cx = sel3s([e[312], e[313], e[314]], [17405833224461846119127359023602459766899246377474167154738658246656617261320, 17497966949182265924717994126031328897613192226672854325764486326873236644838, 18112601253331073769860162727184645241197911130662557597456857637926799952771, 18917984642138666446882277898695258545411024830699319452174655151221791211048]);
cy = sel2([e[312], e[313]], [2379006936139604897517171125029127132096844925377650383092744055973319489305, 12749848257678287712950295235536433677019860991481258729313170570275169590140, 19636804280533422414605179875456610832289030857729756765481423873607782896032, 1918232436869295272222782754406246415048195875894409329377075908962690232744]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 105
cx = sel3s([e[315], e[316], e[317]], [12917351824629483440622737030529674983967542988637720886395195031194160632079, 8841322465723154205678020011172362816775587975165151786897606627457187155545, 14002729598867581256643018976730132585331390790166577050573493502425421127182, 15268061642248917754819598857052007481406516866069427006418085798086854466171]);
cy = sel2([e[315], e[316]], [16674117998706559220643814233136742237729068875288271911312504301619597199572, 15156988565931490695937923747057400310765196912391035444903438612244254494193, 10444568487973458741284119360757120950097746658650645740311119491238200646302, 385547467860345680569692008987772843718726855128251196487129380665836896693]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 106
cx = sel3s([e[318], e[319], e[320]], [11485514708661668839797104792911993330100465395538998907154500209956717209980, 2378564891356297882391172511058064121371341057541144541265151112602629407486, 15431113736930357829525054375951018432490410667610553241393471463868088483568, 15128200972190674116782495538728842150282218770763850888538540847691112710086]);
cy = sel2([e[318], e[319]], [9353349283824572334689034791316525426505799181965760097150790472211583538470, 2565250682258865603262212838934596650511603775929760392607203509225620090349, 19046693709474252308020355261538860605259941620276924614654553264840108783324, 15978910116968143273641610096037639009526883121076925418594134134597880991636]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 107
cx = sel3s([e[321], e[322], e[323]], [12732753810746517185428320079630798046136898905138090354428070504022561261129, 14570979590504848605419638850092710612576634760731998010991154705829891960303, 7081876654999237785822068068775175823259789900038464857602167050792131983158, 11911397750859796885754857056361505572472692036239385315518934824432070976827]);
cy = sel2([e[321], e[322]], [18703753174721947326863540292822225800192529767109903887849391280378615950879, 19613778040124100165889220227898498533129133505873538625549588791740345005884, 15039820717144729975607443780109118368904218216499993640810787891283371396202, 7893305471806697580362861198809218871446498187812275173987543199956558198521]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 108
cx = sel3s([e[324], e[325], e[326]], [4396441250850868966014141809834014631796411613521413364533261157108807304791, 16836648497150572549121598580118959226192434996387135129991940567405870268725, 19465159793724690099931261171165210166819967882352842855510624454147581274670, 18758053793437253746142721581116755417112792746753684636213054094477781477382]);
cy = sel2([e[324], e[325]], [2981405188098805378415778407831807030725264692497108694734382487084076855210, 20469108288868835484927940943356623938045830438424196869633899618683134613519, 933161936100801959708943470285929527457537321589386575156679532348625637985, 269411351035529607018992916380602655161076148137839318392666564540836404599]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 109
cx = sel3s([e[327], e[328], e[329]], [18448980711993048271679830178954781281796619509660919482566515137849326949705, 19744948717433186245821639271216553763028577858032707139265783707853921912155, 19819689638742986969009459074952228930363474994050981268236002838584672060867, 16852310388498099768769862489306840010510354704163417110628769300551675410617]);
cy = sel2([e[327], e[328]], [13538295481673593444396948705042001770075594914797407330259513771278632533788, 14779507856773747214980057665178562325159137267699293184545672938786460137545, 18422483889209125213732972603904783756680200857795267276573963126785961918198, 4225410028652447730956912638069668360808266049871102249949930413024208501463]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 110
cx = sel3s([e[330], e[331], e[332]], [8789386218557174287787274081526754120821582438440596481230009033085305168336, 19604730670978725971286378588091820043225493993475360080974783305559899794334, 5754400819903612415922678283536801620301085919072204701407326554289862247, 8133367062275595631112870441047385208403330263311352404563334748971640119238]);
cy = sel2([e[330], e[331]], [14711352054903619189890311113670897561016852508413508359380114647296690234759, 15505081148609421707654891794900819606599284654426944331953154100271365747946, 10498745521808868190882616751430118808278388180031887838543438537592782154020, 14283723444930116423678497723705206282538086486601870839003576853131844860728]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 111
cx = sel3s([e[333], e[334], e[335]], [16410879947793378178852309134034691965068173351773904636443113803287073468165, 2459742793248426443467557681746013841012911230130900204552944771295773437965, 14148653292536659971692314351826075143664660164844520450779907656237062521024, 3823568337665129538914482600317854425115614575078537531810182911935066246893]);
cy = sel2([e[333], e[334]], [13525280335627612179489028500357999227382280656020782481971742893960563718069, 13906986326008385599879221793305773429690045797230325194617940541283670975066, 17928827609489859058711914379940226888033289004797111427100202351646756410052, 7751873896780721346657011057490735623065509677587909473561532470621436328656]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 112
cx = sel3s([e[336], e[337], e[338]], [6360670162449266467030644276184864100593477111108480032796373772347480922189, 6238026479435781753480651584008291445457129357178771800497280501659229824509, 14372912505742790548866622516086728314858808340582492719789600777407852624706, 2504355035079143757819920622529907675398702401030398889002491033376003993290]);
cy = sel2([e[336], e[337]], [14257529111287275777165336596087530152135443364949890695933859730727871380736, 362630247512640601958597579829458123399369864147591061426591055098065517091, 17799973102921706872164223253101644481160962872432375782799635148100439645882, 16292554915278539427322523921562887226516459098783274424269678044297404132797]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 113
cx = sel3s([e[339], e[340], e[341]], [10885915218940734071225780147170174316285574070557833147925199753671864395970, 16952199638513201931184233985077369412021694081253114169931799009969944845190, 6579022618957621849920927439620464464347948481098737101648586523931683396941, 8954730328909621308689740172956171586217761959578457105814991014419829084276]);
cy = sel2([e[339], e[340]], [11029057981581926429073650712620964484769971154264787930046960173769123662678, 14057756519867963926667557918235357382317971790756175535573262066939972782226, 14508105580605381633693926053140229084417508695027158358695356916669309852365, 8985315555716651207654399675191261186115135312348808559060054412234307291987]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 114
cx = sel3s([e[342], e[343], e[344]], [9591625063099557813317657356201310094684652614430671855551305338577894715651, 21710627476302748728292369634413673464477226906421695181551559967392730749884, 10189696652015358480306279349674126142601586910844054141319090928400967920492, 14575448555178809619615329760249104735737622500547600222673171666044253032327]);
cy = sel2([e[342], e[343]], [13661097518448111362501604180288489621905168345464166181035334250815558586292, 6541927678640542532346030316589325212935454830056081625698359290342280209696, 19655534040611331062875671654696954076416928174908705322979343601347718766841, 18893407984789248251370377180059349323487262100431967496838185583910928677618]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 115
cx = sel3s([e[345], e[346], e[347]], [18886312892727437565309004732784060353326028914324367568840970250261109059822, 4969806713830542782459289156960092729650598975239889678453184524343618399703, 16622981471374298426508813360547940582831388597832992696194782397307736766285, 17207217606628134149600916884515052475396230199786007830822049511835023327746]);
cy = sel2([e[345], e[346]], [20097067895510901824034782908594630518461908899922907976633298936904395310483, 7549705567086856493177008201999701185795474113091244286639270279144087122600, 6359914741562734059777896085058461481450840152242223222499923214787802554266, 4523686415566243191697029234004097207393002925819292838991423859908963592134]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 116
cx = sel3s([e[348], e[349], e[350]], [9611980085915454916721710377398516249069657290776790665729578385653465657608, 2808629496317279665377941162907583528406102092075003683612652910715356989065, 5146801454146059628396374424703327885864890381251241815068083494646287896482, 9712822633793199870569132733680515369277288793857035023884821044404624931246]);
cy = sel2([e[348], e[349]], [12531050708955702438977554896456788618229483698488185884652134859969233228127, 7759740123661798513430229604959580258805004199555419745903987161601748379417, 12676630374277918228347114736241248443643025357735194824989982902529942631987, 7957263793605029493947914798589160413665834659013858298537818906355583201202]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 117
cx = sel3s([e[351], e[352], e[353]], [1741783015222897367309800534949631760951606605798891132137371646304340462458, 15753951377666759323512681415584732767525844411650049393938120048851867306800, 11318371057965241278094291737048639440256637452901941620275041654781038395027, 9043834682180335510097190442699980857932890158044577184782692529141130240824]);
cy = sel2([e[351], e[352]], [163811524362553669200342941603136686901966525127089114473510248213711571683, 20253563341205755839890642239029020576032044419644567576263861445077574198624, 1129293390247992239629138633531986375671761935795719290973869330578475352706, 12864200497534810115296604114235985076138506691530959360993894765742849428715]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 118
cx = sel3s([e[354], e[355], e[356]], [19845239752872171546325855177077796460784181475810291663797620022786920823647, 13524819092286579506826904337550390593582530067994137276480823345309729489925, 6812066149319989921217367650719188106577252681936159930531352608504453614106, 7222950523682776178187164591717978364824407709855563372464941677077475909161]);
cy = sel2([e[354], e[355]], [10413380090476979012716640518612591288231919255093118763710930970879877622297, 13124406349881024599134718908760433545313158896610258373843772982921905937617, 10544285464977662192736078007137407440374594005235468167522962555324745898878, 4262511480267656654185538760448950673777806215660569720854482040852407424457]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 119
cx = sel3s([e[357], e[358], e[359]], [21840644145325684882015312401601386817913954005861480185552664536266852358123, 17245795366378478445622830709744244736981686761608208515847580487483274745119, 13807005991933596253278252430914713127227144098393113439031517565273756047729, 7508257045596568083350722191515656587852775770850324460219207057837744147846]);
cy = sel2([e[357], e[358]], [8473655227220833354585864220301666825011510607427101884196854510787991763100, 12360766780968617496459580910362246207458173665456601955392871687431450155437, 16167977026195109940196928407142099851728373085986722415539043108707307260209, 198020065443013508235269047245522994471757343128188653900779810305583184096]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 120
cx = sel3s([e[360], e[361], e[362]], [408538855946993109150255210001390137328762855947155164309686603040268044308, 9956106896094805762100856187967638241058986877712947272175178827260922476691, 10413057148806203104120616811444687722773209463542545789320471445420824622479, 11902530720628689665925185225980720963660904880464037650526790156354563593259]);
cy = sel2([e[360], e[361]], [1479997830732538227417547327573357263920837878818360220214252494202287418999, 14987839414386761194654231515173353164503075512219993482548242568337943854755, 21713504951370328462347781999791817908891510961297311340202728964936620298516, 20863127910126532592439656993995677084099363872120709138917554483343369113988]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 121
cx = sel3s([e[363], e[364], e[365]], [16909060815089078676939420644976457427406147473547024017569298235433420995548, 13780618743481311116310648367060473410410597997822855004264478650194424563904, 2732495529118703111995546569867225395498452112166729675036576016860030980932, 13122008905793271330592610678764878579485569855365858119720314545298458579129]);
cy = sel2([e[363], e[364]], [9691045028169014905240668289132134803037917344396639164551352440947925851528, 3058069811496358922966440231506430818794592620746845318344939704361344313857, 5622098116652966523875299529800829301718212684029447361840034988407307855810, 7183269074283900923163991117263230892311528827769843151316519486217947924186]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 122
cx = sel3s([e[366], e[367], e[368]], [20571623498624005071141088211057092924213194074152586837454876463843418144025, 14097761035973961045955839030064191145683851652701331413184120292691554339371, 4700343263415821617058086844751479864993855871131720446111591033305616384725, 15018715227933376511503870740434993985805930984246159457731592079602230709953]);
cy = sel2([e[366], e[367]], [16001479421972757821409642160488722706981473283972847385882762682377724905156, 16084059586346766494553050527349239192146155351545756557596881128274718933483, 15099192410657454417038148697642033151361229914558920712490911402249873000238, 6321931552493003117300598295325862984882362303961074819842172524617810976022]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 123
cx = sel3s([e[369], e[370], e[371]], [9888014007610840933022906589732806947017424423907994528302713554488676542739, 8913934326838155827928873892003131738033383847534784434581587200177151201442, 11175569252941365912268295578620074710236065357166442341964835896122343271089, 14897216243038767404517178131890350534529367853478353360851740975433826101343]);
cy = sel2([e[369], e[370]], [15251452715683470293001422999667336542311051361914428663773647008481320118023, 13776813195393840721224885537714951191622587841642219673672717728440679190719, 109393055477786022036855578884727112792551641118563108378161158873180208830, 4672879465153093973501790898266208077997221906104002063988725461236876037213]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 124
cx = sel3s([e[372], e[373], e[374]], [11201877561392804928547433284377926158320532448010089457664943460838007583898, 14898313039936563609742185951856291683792301837166735453885728355621976660447, 271087861779394868518887048853047396941902217944929345703753181641065491942, 4441061173173027475223782298768839441149677456214218957851727123779445089634]);
cy = sel2([e[372], e[373]], [17554707027223374526818340909253875671094356182527312776837442099008513816809, 20394478950504145529480516245504739970884923781915405632423034600555134724554, 16722605284146576015540826794584204150250626411625717127438407440061496436970, 18186321490023557384895834600063402151493085858585827781091438725428737294598]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 125
cx = sel3s([e[375], e[376], e[377]], [8041169655049264647027531522783115313651111026520000925526843693578880103225, 14515227610041424277087375692958559713914998916629738058046674629183188354305, 19607007966889476958718540412171510858381328905787578252786377727252482454742, 2784733087979918000560628875496578392394872735862389774966301201852627273440]);
cy = sel2([e[375], e[376]], [16996116430274827689271070440218340032465717731948638724397047789367189212654, 1334527779675942376452476259926180292226498546209192760351592699867703388666, 2040984273885096997446285553479523685705477968103260410171803510149440153201, 1362381113387759937979242007199225976741286448134891397298462226220340605980]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 126
cx = sel3s([e[378], e[379], e[380]], [19334565048001467439446889504730002771044189757270166846813098304840682799995, 12950908278008251424596267965839781465537497199604011584300739900170800951940, 21595247577936157693500985718654956851081515776736906827009279412148715287229, 15215490137474227465600889880755209339274086672218612829479984354294020155457]);
cy = sel2([e[378], e[379]], [11177666514768283886285136134046021748603781779508224469021361511080086667157, 19019917071840025176852012694579443932947880720292648245869222295962307004975, 4637723565271538497699679545822400204099231070875646671160251633445655525972, 17666228617432733285346663026898759021573050617000716798909504211448351974426]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 127
cx = sel3s([e[381], e[382], e[383]], [10764100134342681938975151936530775454161936697333679961141539476099641645903, 16887585392329741143712714812495679688982136908448490321095843300899468374984, 17732836192725467148065242235309558107289861496038148884513643994394428900356, 1445275363508375975763521380916891145219085429516411016928665376398954093593]);
cy = sel2([e[381], e[382]], [19850691100864531393976360616243718992492409320965998539447518686463634627384, 11041690436464044133197365654525664032353519287590211059695239069687237542566, 12282683178748394297470306056106686277334235538468988533692942720363799093795, 21342615132598490749588725326967212830166119543678585183102318245731915882892]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 128
cx = sel3s([e[384], e[385], e[386]], [7984775939876417845202037337929702281039643807160799398396389954446436630245, 11385355274910748832054888360458973063107383418973550712148639893241354902280, 1459026779105998101465829026524789739182470402517704469029876736898952870477, 13412666792048974377925483462948441322790663427949756029941851541794367956141]);
cy = sel2([e[384], e[385]], [11644088529951120466123058306783377782553679447618569394424538939634266570688, 3423766185322892807020818425845766412060736093511436910964946420904954554780, 4248997486365074893462023447486954255437098681775520477410894095041115503490, 13508520946233121439054409300327739993661203591041357972218149016790406863855]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 129
cx = sel3s([e[387], e[388], e[389]], [5565157198993964726485879908963280627890845525340341493437203971709365228330, 7321058630137598328136197614874359518495943608220094707772133348409941566403, 7424926497991627209495812948930411917848701932818206777924739403931504666904, 2952280234707044917845773867363672510563637804197143708410321227590096039398]);
cy = sel2([e[387], e[388]], [16047978233091600592523116252839158499254716982332498268149527514947495047441, 3013461674923738179146278200182113922630443185951298626004001204030842783133, 21733406038088991240575501132398939052212396619770619197864537159847335678397, 9758173327391957613571828756022551933369392423107899686458119829785341358149]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 130
cx = sel3s([e[390], e[391], e[392]], [724617195994552100441707186007100945318061137735042194166321801565168264994, 21457482305994995060621698878673403410439584990848189791210666985898821778689, 12733018351677357535096192491479720026355634001914123270202692797811692793469, 17876157828650849091584102879830086520321631185862731111337702980715729860154]);
cy = sel2([e[390], e[391]], [1941243639179655563586549731833523575056282199989602716546318426577162114198, 7186671745389328078718719957510862463188189283547797342924706384031236512232, 181655793349501388675021326982297619804658251127556562657041847324134931318, 17955220324559325573119985254939537965603633897040077737890918084344489169000]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 131
cx = sel3s([e[393], e[394], e[395]], [20917363825188238552045899784153496987535745925685770873105753565860443082365, 4540090524117153259059229343653410962125958868702729157110889632173091362337, 19931748170703315405614719529478161068009956569206884593254142678501117968416, 2400060542928241404744010463507020801241694851019173560965950546401444426082]);
cy = sel2([e[393], e[394]], [1745736425002501661522536470728945366618822522645696668197436988525466413140, 3366347972505547411030140128225789817592493957844838153202867496815084725868, 13538672659394937012305631615026094764214309199641714104321427476435723762022, 5730310969197975636538358956003546448924042719236605822193245706535947879790]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 132
cx = sel3s([e[396], e[397], e[398]], [12673489410414637838905637938820402546181123854591818062100393889121109718668, 2399760455052989852989301770450241617652861646522026007293921167342274767344, 20212599267512455026947565441242728025855774594658042161574807775907652589242, 8096283485634551421043683037450718803162713602325821677928898619562706870069]);
cy = sel2([e[396], e[397]], [2273218791680662828916671149332560291571458847138066661294611637128783792792, 8189321225342615133315741008578315746871762722980986965249683543300354337817, 15342161105292713352374449802912175534449400959133109035836260415735518836755, 18075013689729624974967362235212984989450911765049481574404064991547015443791]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 133
cx = sel3s([e[399], e[400], e[401]], [1596291013949010721288060595532569432608538778619836480784785471074053165112, 6808491683819461025655595089437806112418825101974851283793281398274802390485, 364241503925827187366795904611796342209607893955620582589568264631586955422, 16490550871285168246186419126591524969189857825357227166657318003550977024941]);
cy = sel2([e[399], e[400]], [7862378404177401992071889396713852447802454946236648304807328682371781930090, 507291250759269099980701396020232970806066743976022636589996988193601483784, 10744127551738752560827414410584235701822856001225517338822143012287884858602, 18241779151498711099077315181629505156252250432591841498036131464452558240559]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 134
cx = sel3s([e[402], e[403], e[404]], [13383782376835328120051264492485947246229335501182593669024066132006083860995, 6829659109797487915393241205795046921708391483622784165963215585089039907693, 9316519590383340417002353253254231934003449806173856616162378794199227402893, 13002922510988749141229072125743986091046064285797312111247897533544865920246]);
cy = sel2([e[402], e[403]], [1452388014885069534714863742557414467294079407912495717272255602231974271039, 5900502409092025397559171952410984687860230521181044855453255892660864354438, 10043095963739821148582141213281494171132379314509020019652213752752234376602, 9999295030621233000765070897582529515356078631699063530749343953422947829219]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 135
cx = sel3s([e[405], e[406], e[407]], [13165533527694513928104129943149460933916076941607396715443729707678633985673, 20294369464168299590806576821399517301857816000499415634107985306452722815938, 6067645363539607688922626118164207320418666861212948609146588413602170467017, 119932367132867885429975847232185792475931817114142487620518936723703313296]);
cy = sel2([e[405], e[406]], [17238425515895072477563840544058923640858290538130746390995636765338905591675, 20628042696308823655110673878535950075986980894297665479048269813590306242580, 11749486899455580256560135562925052584441889327031335669536847121302580177052, 16957619631025354458723169845456497220362554006891490260455748609237426050971]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 136
cx = sel3s([e[408], e[409], e[410]], [7326992374695153334569399469397596928696501586886381702972942656080738560504, 4198555626333615585226486302590784054103224208504401294485393840072962221472, 18288510281806332963207620050180295922486954421289661405933207406160563376204, 19378648346334975363564386629109544268031565617795572270340255835354171953065]);
cy = sel2([e[408], e[409]], [3441991977044037545935620478935168226411039028254665140927991316702138513190, 7980022316348851053079344973315144435710609854183180078433220232446348072790, 10703403289781310156812833248447222548151317595810496437901793212311982317063, 16301246072292511450557090225826608132244132307038997545230147196603338285964]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 137
cx = sel3s([e[411], e[412], e[413]], [4380971751033847027929691061398944531722909263311553031455521197665070771642, 1958998764514462202561805635784673640011091472752464180193064104296547581169, 16607632498550062722823535936950763735998138401664871177932105851574722673362, 18107842395238833528194122400147411460295339366691168281515267029707554163796]);
cy = sel2([e[411], e[412]], [16794605741797752486161164743285493892529567663448780177764044251817860406839, 627364605348057780240790756195705309805910423716172983190978634837740895756, 15938340690702031578469687601244712133164105954943969813204470601233395408177, 1337728022058609756453976167140964506743665540101352471912041874198880786028]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 138
cx = sel3s([e[414], e[415], e[416]], [4325450975911066881724043517797022496124195434220888316197251865366294339361, 16239262892194658073042878979066943080253388067983326658313518038231343725333, 3224923392579231188607529005374853676842589239602348970956358059045513499844, 18711810040957806004127569353264972856236116117792057333129328498567653245337]);
cy = sel2([e[414], e[415]], [18556589125306655880844231674670238467511897504977535323905816448582480367724, 14450907030938846250134541582271892920169763336845349109491176054829079021938, 5489164165718004081061600001298776199757130654902992957321875892970948684039, 3404126456231281994449938636645452663538090331489692208486381139765931389947]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 139
cx = sel3s([e[417], e[418], e[419]], [3049906494165633773067493912990013841965806179225048735919293547905816967010, 2425405604681482172566807394598240014734338608183001729881716084701331638207, 21560391195338031738549905898033672840916947395960523186297949490337780382461, 10640880946275949996544592530048605056441276931537882586193904453232482475238]);
cy = sel2([e[417], e[418]], [1139270967545262231620743596254789040950691396231510347534297369410226811042, 20852287956575668107697863776884710196273757688539515338600627283890571581133, 17188605966302742252765339963794720668370341043552053263753117294010969693650, 19246586050423626713095252320183688353765457408019346352862271422811659317777]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 140
cx = sel3s([e[420], e[421], e[422]], [19942746034266536069392101170115851306620344112551007974939114086497358930858, 15726708481134151732276229872451366695420040201434018827381159241014716358033, 3452250047812572894016965388138239348795538732265416477858038566576272340399, 732825901760241932909222883465959257672029209130800755766287912812473135470]);
cy = sel2([e[420], e[421]], [5234335526367392822375043936890479400588416815383747301372644960641216357795, 16682782393317738699538698600037172468451638588454521003611347304172554322239, 4800939729460682232720559307513657730880675292200605768084865538547688695396, 13002618796997179002671199181852958465089986403190513123030050511152310206971]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 141
cx = sel3s([e[423], e[424], e[425]], [4345203866646269633300579468877411954334981515932585752657225898484243906660, 18369957391582635573293322493321958485207102003892958136897534329158731684885, 20673831086732472000273127370905823039882723856850376643114084876980363716192, 2498213507326390169362081908041456736901489034606083564552630396661416090091]);
cy = sel2([e[423], e[424]], [19711785928362785984568609948298550809737208754846854010480265206080190724688, 11436630733281926268922633177556600595162960771369546050376297927685306050908, 7773194831659524501769470153758921383337560398544153003929463015874290745463, 8133306555008250199402612262687855812899186562206213570420163947809045175265]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 142
cx = sel3s([e[426], e[427], e[428]], [13604959715661441436052939762464429298226713418171390314110026091418525209941, 771054573202666486644315008474869467749501529120937703475279735897998473318, 10650739155896636131407567213077995361727149157766675911133814003745320974607, 21082274336612203666519840927907859383019309974047946161440422017817660726149]);
cy = sel2([e[426], e[427]], [9106634253925907822997376723908848470389744101982447244238790923479221740587, 7324910184007890101804849358851153077116609835592182327277588695666568522132, 9210749700131521931808418873690269098719063379384664590576822932928021903283, 12373345790154524492998539937744274645461345882077071841080883186883404184026]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 143
cx = sel3s([e[429], e[430], e[431]], [12272981972646946567553896730199881959247853499104488943992635249117595393209, 17484113948306348142106921779441669789323552473173221235726133380929727014173, 15117556748390824311921483809280404911428464810641842112990732230853500342878, 18738665459003240153367275566837691463796036422817751002779294781153509048410]);
cy = sel2([e[429], e[430]], [12840198036955871442566173317906222816787870441489199428401326600711994709214, 13447048657087191261352674553209997835888060694120420289379298057286058954919, 11085124394828809185369563175800089294678889500629428639251047427113804175136, 20040932616180013985013159566209210337758333701488325181237556234029685365086]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 144
cx = sel3s([e[432], e[433], e[434]], [3005593847772820450050205074163314509976806377772621088836578637506564062913, 2910567614812792758847544159495544141576095133298651646543717734234356651464, 8630893570634023334653627900758492588201195084156991103796478188432785900122, 20068438612873289533893462991408376904784837411837844241529573433855826118434]);
cy = sel2([e[432], e[433]], [17258587025904856892544250820556722922327972240440200527118380921147955645556, 9839944666562674042904466515196204595921896101136113309540898758440523509232, 382264312380680546118029507176039576064064377468124376294215202312670233326, 16859633470889096937094854459393230196320754799783499045789361347337904723211]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 145
cx = sel3s([e[435], e[436], e[437]], [21553262056684585969628674122764109775958361035991194009613252605155913211334, 15282636750399879299317591027894754559134990135454294656134105963760417995544, 4066930541781809252860144352581968840798983673586834922803928000950012716773, 17266825085778436273993504052249489036678132768169211810048007631121526004292]);
cy = sel2([e[435], e[436]], [14469270633466381305852216281125837079646617198515099740000541993840798471084, 16980111987593030332881454298183054033228595894840772569146266548134494583283, 15118688184376333116924615779850360769477969453186921964192734694461085893102, 4748807943449256265621737370336238625547081211863390407052811770007138872316]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 146
cx = sel3s([e[438], e[439], e[440]], [11763347508086007810977359866267798246514404258245360557926263268200652076963, 8663905006927572311188991703236656874376542152827973004022578290253373528008, 2952845374549988741320721621283121797914244173004620545437372716814928986849, 17071883097921153691621062529879599274949735278299892231358334236565401545899]);
cy = sel2([e[438], e[439]], [14706162498378202954074913829047629685039231677186626739445882650545999503202, 1719746349330736449674857345290037499267579249273019799523377364214790913723, 21616731410397798448193163892890526448374926979106286339849727909287686706845, 11446919769449393256780992769707214683226878212422736672766658759052425409242]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 147
cx = sel3s([e[441], e[442], e[443]], [4356994949172878276640972387865792898708144237321291982532719592191935134502, 9058912028451204788275313382642068418310841490274106696805181452416351257146, 15190160120915818686650557755704440198069036613617930484645880424887234233075, 9960154561010441532105561845082645172957096392270554555453954413006726871798]);
cy = sel2([e[441], e[442]], [14574692378125259586817945291111936727424704391123959334117252195469092200764, 9224728228539828897416026999778106548490158473228676095012930511474594231477, 1760463507739730034367125481096536174852992494939001755761219582349351757169, 17340078450196530212205314520279311841731993777309479440929707007860057490354]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 148
cx = sel3s([e[444], e[445], e[446]], [21880820504467716634106664909402072165472960350877194774465177915127008092893, 11747606579643600398471099307152208653405848363842457205852065247815894902054, 19027263041564841350573847395951723454691080012198506245692747602145336686229, 5632682422077314837831565983660289273448221389165648008167925020530588300924]);
cy = sel2([e[444], e[445]], [5182168744456816656485869911241149693404052223082761825064601932558781730740, 2685937932147288674316610675212322222716444961674715249218650895750571659552, 1912852125196207140975649985472776011293820313776376659814516409955251806791, 18263958114524880676274451483937610105571465623681831140376587635788141241088]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 149
cx = sel3s([e[447], e[448], e[449]], [8936781701927368370215210870827508937678765478808217533286287559934624784681, 5108431664028439851662340341125863641795570652264053957564019035084276122804, 12999653496005517730722186355139904948504508219343877303366358022761375044402, 19179622495081980573635923134343351242929014436693872859625873727501193848932]);
cy = sel2([e[447], e[448]], [4623029543859886044767307470074323247069187031547412019261660683452990785239, 9857015684855568488276378660083416741199186578332924215590492662945432272825, 5242391447932956625671668911434466570194372869876929059550830464880164528131, 14646928672286452058469223988095085156895208600523868135204725017248298504143]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 150
cx = sel3s([e[450], e[451], e[452]], [7946459614521142644206204774850419894186577869297360917934350740375926112382, 11530085592691934773947896113217121596676226719554558175458752626759168307130, 12291215261278045612022495371137973264064622535432110273152233125306665396787, 4442266885858584741818610179233325487185053295954810407262511211378152048331]);
cy = sel2([e[450], e[451]], [20393528966549387266343193152712146799161036298032725317477228673291507957942, 1831259860608244620805838343666664146008857962101286629882205237950513972028, 2581270768505724914793947599867596421087089340177029937008824731251155270286, 1824038414762784797700995677077189626495506231241155951144255369814082278582]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 151
cx = sel3s([e[453], e[454], e[455]], [16996326686259093178712301719114535464147004200933701699216923172711169217776, 10135668620867881915901635109225909232593721615476228193005378643989870282190, 12684696285143358527008494835928613367424428569071148860201922633463847362163, 19520340433574445384932755965450431313046400213079154403779893187900476007389]);
cy = sel2([e[453], e[454]], [10879703765081907416589976314120373073533854885503210038919805342729980088501, 3042952377945780941440480619239495862925076770257741464841490662991367990723, 20568201167449878452522309826171296534890589395210499691162182782776592901489, 2515435614825363087293388949409937340469196878839891206929432371588941120828]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 152
cx = sel3s([e[456], e[457], e[458]], [5948355082391370971277814822201259570199411254972015395356071689733858457870, 14435295688288574008552320445654835668230448171821339773392204385711009673498, 4555707692840173328761632986080641237899354311390885658902712711385985152474, 21377793559898523325502642621273525075966615158530502938404139072744665720725]);
cy = sel2([e[456], e[457]], [18781938632634665629392534748457372928296731257744451684662925940692495070899, 20870582266287640319635222130472633641883455183531701982867810507045631654099, 6255001622610081365809867580322152519018111820804890853975941295493185079617, 11444903546950465193484459453464362458126976218066241321940461471249831055834]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 153
cx = sel3s([e[459], e[460], e[461]], [4801783634053958699406131208260321653724147389806778300442394152288266622390, 13657947007455887667569605985083889328718870615545221619668723775205747840135, 177598511756923881728697053947837521554079408931967588956714727282062478754, 1374290142752108446259268973165307183295759382785138144661109763848127727476]);
cy = sel2([e[459], e[460]], [10503832530625380631086165586158401732075983866290617431349835924922749109699, 8383317413774803586670187834721088561764237477263859389570115631886656905028, 2834233504802602126712103599378293010472650755759227696185340490923006971103, 17330582798076118742935459828744886802843487551551606246519220146369990307779]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 154
cx = sel3s([e[462], e[463], e[464]], [5093610893249308867168031458336741939196884648123926997975341654608609426830, 12248279767532955250746877738475030196514076889129781370472666862024900770669, 5043009492124624507652527263244758360087085758651362799261288863076362039187, 16591909200159417412409462652077399999824413751859530227695887196356321679228]);
cy = sel2([e[462], e[463]], [10952612598118313917631759693602817846928839860096429550603703046117049639522, 2884939241145303979172401496138136665819626424676215132904685536232137032921, 21092145374321584925227081195844245213760374840107123770724422721835988876958, 5499840197627421265036310285493143039360364243394878011782966367266344217732]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 155
cx = sel3s([e[465], e[466], e[467]], [3794104339739491010449122661216407115137782001618163380131794160705537757426, 7514419529276933284458458535371966876401883528785013067210805765651582633130, 2534189532451386749189970776179117832798970009395742348348119108287813471216, 5610243014937776775874159841646817951854662385825951664842167532212856045068]);
cy = sel2([e[465], e[466]], [12842968623255283384772731210441087433561383555541999360200972373794310794093, 10823437952973686303915120116380996262045441725571077692704581218749963605907, 21253964658659775229061107104903539871763760188604842330476347939642955209002, 1745535366815989039402026181267179197840739481539734000808670009580269211142]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 156
cx = sel3s([e[468], e[469], e[470]], [3459245219635302288341483992140272707638915493010622274381776793623419230591, 9849021255480129732487752167924340739614806540698786580158805033907788030853, 3255308487469886623287718398314898379309460957968181729113829918571419337145, 15359614079733122216507425018253600855203543497608695539122606260839625565617]);
cy = sel2([e[468], e[469]], [17415928452277952995861857592997544802223350915817518744596816398543561612106, 9999856236606156376100952785476675300524456948913069129769906530665355058037, 17734497746752242925262857913765409819203458581088950917188119245918082092030, 6881580842463060802624074515204787264906621652045323766233447264566499944530]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 157
cx = sel3s([e[471], e[472], e[473]], [634964597278986129282215293208138156361395902716873910540311662219517773576, 310253852479958835592393232442887907344502522183801152945448588489452412569, 384881480274621505303330466062621612997526527075542749162723700081976881288, 11767445114097831765826464678890553621483551558949563523534328471079851963281]);
cy = sel2([e[471], e[472]], [17203635141310737823252743409317633065422478971915442288649227045499339781109, 2545094457118912372548408336893899649182443951551613850781196845141738637170, 8609139198776064973664903858401535131314034007074283879284230416121615542308, 20092107484372320312567981037155807130829118997137612522175958096520972507336]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 158
cx = sel3s([e[474], e[475], e[476]], [20098437969178934435495041700635313630962028038875583770224318127835756299529, 311104306589906971684844795811359683864786473908061989245919427082915904714, 5007249687217418940511624233021226494914521342148545152148356064906320432035, 9785851145981523672688289938894315309424412779439726667571213830109657407900]);
cy = sel2([e[474], e[475]], [877613904095171787446316454384924363436490179245069691113043218080238972652, 15255392602742007855606168874483544819258797919038984937824266131810915403967, 3482868076428758563707184390706074120455579821747810434457575250407348632455, 5737555899585712614112644175034540180519345050397396205967955592318835422324]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 159
cx = sel3s([e[477], e[478], e[479]], [17889638686175315317941901427709143202478522471798280927986774735210637820526, 4586587171981050785204495209615167868746399227792813638212786811256473778221, 1864752565757236746122736751796835904389046064841800598816325031089096557478, 13943403942544820674673437343502779310324858400636923221774342029216604251440]);
cy = sel2([e[477], e[478]], [17728898667133884634264046347611298588924985692465583707491826367590591819161, 18365428070394378833051912713200271982753415548931989923757430748929339745094, 13355801165885814561827651110098104649674895992244923613944279081535896494292, 12718254346735593182641856097514926990330253814732909832265502852628068735026]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 160
cx = sel3s([e[480], e[481], e[482]], [17159516188699622404527134263356371503443962451842558111890221401200764258125, 19697000438877661546696672369476849653861527230741461549059757921200307256689, 8082602544025295110701438493605046299287009032703969632384937719700791606339, 5936552380580117855548116310401989958728171511356588061450350806482980900531]);
cy = sel2([e[480], e[481]], [288697205606498046198642124865852628925547477970007319079115715396675917499, 11438994931015502912944770174743669059446783563412696311667974558402876489825, 2713576975757110627428489368530113978475830565467996635364633792472336700891, 20023822454992925006561366839036620580908513505208980493011483098957399405656]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 161
cx = sel3s([e[483], e[484], e[485]], [11476903323853344813827041345787850966667514952865946400953029235796901464022, 15662688482882450089332164944545567115920791913333567306810233998084574572841, 16165244090421658682362860955446523155721204004465368156540492359518946703685, 13233236504179066734589049314166320998745790229936719431495551951291164368688]);
cy = sel2([e[483], e[484]], [21544495907681885621399294493301860022991247894450553860102494438499516461036, 15070356063300726246376329439697612629246560015487953180041607494107482212328, 10932308314438454016363769449242767120417784090441698745502660483728820506459, 15142440904746497443767345573381088273730091577283493618193631903901402378371]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 162
cx = sel3s([e[486], e[487], e[488]], [6740469135284996394159167279126920754449900660887428959259136317440159292867, 1951789672920637712186229138057234008172951294439716801691622239946406362446, 10614706090196653889949286489862565736131644495539213256761186995450585212820, 20219336380099606710973890974478494924791931389585459347005405927908068729651]);
cy = sel2([e[486], e[487]], [12559437556228574824459283742977065667884462966124147526010574650373707978536, 11353250997656326728675199688614508617263787972463605193791786351817731868528, 9955679877407075213882986027032271351625902587325271136145291798547578901197, 7587664180577472344145946155058239620135123893989614056504418351234639990359]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 163
cx = sel3s([e[489], e[490], e[491]], [11683193590608313373089435698057644614965227085254736967478627707109364481009, 5373593679075319624506848608700634791297845735799356231319125589754901432010, 14330496678432059141319543266495924665988744049796260830269932610430618839231, 16147138941500612947680025577703299264094926996519490683694344514795650552030]);
cy = sel2([e[489], e[490]], [14089407095672561058133609212857713657125336981293206062798215054918146117895, 5921405729554308485753035966317904019193857886291312338471036342984958996974, 14219166018565381341875979253176613205499868708487414627746489465729919459602, 9173206043848059861761039827886516664018988512989876666692360758637877840001]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 164
cx = sel3s([e[492], e[493], e[494]], [12391241461796318677666973225906912103063953603374991439355987755433936571792, 11342324255021537810533271600486943249554637261483201032733188357979300928906, 6762143596567875242093282841823575455167081327592834568853990326935018728741, 1729094316763263611553329689516612131095524285732807879509329720064037980971]);
cy = sel2([e[492], e[493]], [6256323253756510425990684148198273229283967340029341825763386143854418092931, 608479563301898577121898469798459144789668559311173727644698121661161535370, 16118965412641868779259712849902459712114606105053804845952965420804403776265, 5207196556914412218334602277590189653542873808697180315162104560234636073976]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 165
cx = sel3s([e[495], e[496], e[497]], [12090834415198821488072985841187199896460619427268475889346428879276625683876, 20435352555053416469114817994605784220258558984767053371686545934216871498097, 7919766463107746640570694574991853522177141706128568812747727580994437010928, 18791819403195060520893758220974368558662433382958799315116210085990602330263]);
cy = sel2([e[495], e[496]], [11186634643432676423242372187246648742599522445001126220151236883458565017089, 730264789631663387855933585769199256797088038637783970560657523730947722943, 9789319816975923274967045544277604801648452652703289939384714401867885689451, 20390569650377326057430918388837541684089995685084097630788684319064176189296]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 166
cx = sel3s([e[498], e[499], e[500]], [9073477014345643942359994649331122800736234440180113066690071117218958686221, 17848891043122277658033397684650904021333601784635518417727821688552518594475, 8394455238188958480130266174842497177830879983439478526032000789572056999540, 3969215253795918818810265899749520158876595254756141389552909935321879395990]);
cy = sel2([e[498], e[499]], [15421230006761899572959376594938017439120427450367920423701622807634638005218, 691759570775251457416249989322179808019152722619656278259527490301863241777, 19687896560656750069557210923004770524699515901561346847457425701096560281307, 13013403796046695153969709190889488389508063704805702465177729278466953096077]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 167
cx = sel3s([e[501], e[502], e[503]], [17605212659450062681090282709904508607567301109002577655966314961623397498778, 20706453518066591671344075213608634140534260809172831962434708646209603184096, 20530641835252913976176823270868884490574732596806683216254892843407024651486, 19512520336574558609801187648395617364107060095538444150298099264798316486399]);
cy = sel2([e[501], e[502]], [18088283300102077232647028354145534410326244238430555546504288886091850910025, 19624767204537830958950503358240075916787006780432673880401115874844576604739, 13389739174441700308398229420122777340874705736681526274430502297758537243393, 2768660518118504029156154123602101814256009402463064802144883490594220059578]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 168
cx = sel3s([e[504], e[505], e[506]], [3898901470837850662399020072718316987511815396623761376502150466549773974269, 20681259404330431411774484706350104535474957110888110413896201115382255532278, 12146860081497614316907871444885755439616687087776665508013517962132514932126, 10103366418676857183019670163194546750004223272088526675082633522057697832251]);
cy = sel2([e[504], e[505]], [18552945270636575492780160887690665046683842994616480518496617903497833044944, 16280318807141467057522946128901953503954886894473765482004622686048871784896, 16511259671446150110679883995503700110523460228865394020432354340848786592304, 11820015885519382016829607197866756084707670961286078960070207041832708513141]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 169
cx = sel3s([e[507], e[508], e[509]], [6124403322044682705571649214069113177521499060664580284884665715951975035077, 3806547960677312456106393355578152447583324120952390972170284549005371006887, 12796416634735923176681417392847285391386920336707070519873332365264500996292, 18113312677912280033934533469627761267183403533244965210112870702471687667512]);
cy = sel2([e[507], e[508]], [18191174947339798787646910619446409943766046946921136035021645191602921923040, 16559060177998758852323304784771936179434931576336411584121379336820727372618, 13858115732979799183025726471151602712224733686530960054365665740611187232029, 9933192519609817862698304326029579651414877338671776883175639003837130283966]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
// Round 170
cx = sel3s([e[510], e[511], e[512]], [3342564788366736273905106071612128667477972061160313630133110787799686301495, 13766193863701503939885263345152684798552605679140222504700163745347162493183, 18523279471468319520962369406962457727155204375043681943707151819380964978377, 8094164074569624021939357073285075790695279643883973800173037824312344195506]);
cy = sel2([e[510], e[511]], [2329094643034533408459502544740928833981119919633412709248656884170940780093, 3216329736050668550647765981020076413548845117352735257893224753954595290363, 18710403072495673647060422294369054840513840567808020912157404388689648711093, 9785201456176703812798077455183487364035650707229293534561747881523562553649]);
a = add(a, [cx, cy], BABYJUBJUB_PARAMS);
return edwardsCompress(a);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
// https://eprint.iacr.org/2019/458.pdf
from "./constants.zok" import POSEIDON_C, POSEIDON_M;
def ark<N>(field[N] mut state, field[497] c, u32 it) -> field[N] {
for u32 i in 0..N {
state[i] = state[i] + c[it + i];
}
return state;
}
def sbox<N>(field[N] mut state, u32 f, u32 p, u32 r) -> field[N] {
state[0] = state[0]**5;
for u32 i in 1..N {
state[i] = ((r < f/2) || (r >= f/2 + p)) ? state[i]**5 : state[i];
}
return state;
}
def mix<N>(field[N] state, field[7][7] m) -> field[N] {
field[N] mut out = [0; N];
for u32 i in 0..N {
field mut acc = 0;
for u32 j in 0..N {
acc = acc + (state[j] * m[i][j]);
}
out[i] = acc;
}
return out;
}
def main<N>(field[N] inputs) -> field {
assert(N > 0 && N <= 6); // max 6 inputs
u32 t = N + 1;
u32[8] rounds_p = [56, 57, 56, 60, 60, 63, 64, 63];
u32 f = 8;
u32 p = rounds_p[(t - 2)];
// Constants are padded with zeroes to the maximum value calculated by
// t * (f + p) = 497, where `t` (number of inputs + 1) is a max of 7.
// This is done to keep the function generic, as resulting array size depends on `t`
// and we do not want callers passing down constants.
// This should be revisited once compiler limitations are gone.
field[497] c = POSEIDON_C[t - 2];
field[7][7] m = POSEIDON_M[t - 2];
field[t] mut state = [0; t];
for u32 i in 1..t {
state[i] = inputs[i - 1];
}
for u32 r in 0..f+p {
state = ark(state, c, r * t);
state = sbox(state, f, p, r);
state = mix(state, m);
}
return state[0];
}

View File

@ -0,0 +1,10 @@
import "./sha256" as sha256;
// A function that takes 4 u32[8] arrays as inputs, concatenates them,
// and returns their sha256 compression as a u32[8].
// Note: no padding is applied
def main(u32[8] a, u32[8] b, u32[8] c, u32[8] d) -> u32[8] {
u32[8] res = sha256([[...a, ...b], [...c, ...d]]);
return res;
}

View File

@ -0,0 +1,33 @@
import "./1536bit" as sha256;
// A function that takes four u32[8] array as input, concatenates them, pads the result,
// and returns the sha256 output as a u32[8]
def main(u32[8] a, u32[8] b, u32[8] c, u32[8] d) -> u32[8] {
// Hash is computed on the full 1024bit block size
// padding does not fit in the first two blocks
// add dummy block (single "1" followed by "0" + total length)
u32[8] dummyblock1 = [ \
0x80000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
];
u32[8] dummyblock2 = [ \
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000400
];
return sha256(a, b, c, d, dummyblock1, dummyblock2);
}

View File

@ -0,0 +1,10 @@
import "./sha256" as sha256;
// A function that takes 6 u32[8] arrays as inputs, concatenates them,
// and returns their sha256 compression as a u32[8].
// Note: no padding is applied
def main(u32[8] a, u32[8] b, u32[8] c, u32[8] d, u32[8] e, u32[8] f) -> u32[8] {
u32[8] res = sha256([[...a, ...b], [...c, ...d], [...e, ...f]]);
return res;
}

View File

@ -0,0 +1,22 @@
import "./512bit" as sha256;
// A function that takes a u32[8] array as input, pads it,
// and returns the sha256 output as a u32[8]
def main(u32[8] a) -> u32[8] {
// Hash is computed on 256 bits of input
// padding fits in the remaining 256 bits of the first block
// add dummy block (single "1" followed by "0" + total length)
u32[8] dummyblock1 = [ \
0x80000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000100
];
return sha256(a, dummyblock1);
}

View File

@ -0,0 +1,9 @@
import "./sha256" as sha256;
// A function that takes 2 u32[8] arrays as inputs, concatenates them,
// and returns their sha256 compression as a u32[8].
// Note: no padding is applied
def main(u32[8] a, u32[8] b) -> u32[8] {
return sha256([[...a, ...b]]);
}

View File

@ -0,0 +1,20 @@
import "../../utils/pack/u32/pack128" as pack128;
import "../../utils/pack/u32/unpack128" as unpack128;
import "./512bitPadded" as sha256;
// A function that takes an array of 4 field elements as input, unpacks each of them to 128
// bits (big endian), concatenates them and applies sha256.
// It then returns an array of two field elements, each representing 128 bits of the result.
def main(field[4] preimage) -> field[2] {
u32[4] a_bits = unpack128(preimage[0]);
u32[4] b_bits = unpack128(preimage[1]);
u32[4] c_bits = unpack128(preimage[2]);
u32[4] d_bits = unpack128(preimage[3]);
u32[8] lhs = [...a_bits, ...b_bits];
u32[8] rhs = [...c_bits, ...d_bits];
u32[8] r = sha256(lhs, rhs);
return [pack128(r[0..4]), pack128(r[4..8])];
}

View File

@ -0,0 +1,33 @@
import "./1024bit" as sha256;
// A function that takes 2 u32[8] arrays as inputs, concatenates them, pads them,
// and returns their sha256 hash as a u32[8]
def main(u32[8] a, u32[8] b) -> u32[8] {
// Hash is computed on the full 512bit block size
// padding does not fit in the primary block
// add dummy block (single "1" followed by "0" + total length)
u32[8] dummyblock1 = [
0x80000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
];
u32[8] dummyblock2 = [
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000200
];
return sha256(a, b, dummyblock1, dummyblock2);
}

View File

@ -0,0 +1,14 @@
import "./IVconstants" as IVconstants;
import "./shaRoundNoBoolCheck" as sha256;
// A function that takes 4 bool[256] arrays as inputs
// and applies 2 rounds of sha256 compression.
// It returns an array of 256 bool.
def main(bool[256] a, bool[256] b, bool[256] c, bool[256] d) -> bool[256] {
bool[256] IV = IVconstants();
bool[256] digest1 = sha256(a, b, IV);
bool[256] digest2 = sha256(c, d, digest1);
return digest2;
}

View File

@ -0,0 +1,17 @@
import "./1536bit" as sha256;
// Take two bool[256] arrays as input
// and returns their sha256 full round output as an array of 256 bool.
def main(bool[256] a, bool[256] b, bool[256] c, bool[256] d) -> bool[256] {
// Hash is computed on the full 1024bit block size
// padding does not fit in the first two blocks
// add dummy block (single "1" followed by "0" + total length)
bool[256] dummyblock1 = [true, ...[false; 255]];
// Total length of message is 1024 bits: 0b10000000000
bool[256] dummyblock2 = [...[false; 245], true, ...[false; 10]];
bool[256] digest = sha256(a, b, c, d, dummyblock1, dummyblock2);
return digest;
}

View File

@ -0,0 +1,15 @@
import "./IVconstants" as IVconstants;
import "./shaRoundNoBoolCheck" as sha256;
// A function that takes 6 bool[256] arrays as inputs
// and applies 3 rounds of sha256 compression.
// It returns an array of 256 bool.
def main(bool[256] a, bool[256] b, bool[256] c, bool[256] d, bool[256] e, bool[256] f) -> bool[256] {
bool[256] IV = IVconstants();
bool[256] digest1 = sha256(a, b, IV);
bool[256] digest2 = sha256(c, d, digest1);
bool[256] digest3 = sha256(e, f, digest2);
return digest3;
}

View File

@ -0,0 +1,14 @@
import "./512bit" as sha256;
// A function that takes 1 bool[256] array as input
// and returns the sha256 full round output as an array of 256 bool.
def main(bool[256] a) -> bool[256] {
// Hash is computed on 256 bits of input
// padding fits in the remaining 256 bits of the first block
// add dummy block (single "true" followed by "false" + total length)
bool[256] dummyblock1 = [true, ...[false; 246], true, ...[false; 8]];
bool[256] digest = sha256(a, dummyblock1);
return digest;
}

View File

@ -0,0 +1,11 @@
import "./IVconstants" as IVconstants;
import "./shaRoundNoBoolCheck" as sha256;
// A function that takes 2 bool[256] arrays as inputs
// and returns their sha256 compression function as an array of 256 bool.
// No padding is being applied
def main(bool[256] a, bool[256] b) -> bool[256] {
bool[256] IV = IVconstants();
bool[256] digest = sha256(a, b, IV);
return digest;
}

View File

@ -0,0 +1,24 @@
import "../../../utils/pack/bool/pack128" as pack128;
import "../../../utils/pack/bool/unpack128" as unpack128;
import "./512bitPadded" as sha256;
// A function that takes an array of 4 field elements as inputs, unpacks each of them to 128
// bits (big endian), concatenates them and applies sha256.
// It then returns an array of two field elements, each representing 128 bits of the result.
def main(field[4] preimage) -> field[2] {
bool[128] a = unpack128(preimage[0]);
bool[128] b = unpack128(preimage[1]);
bool[128] c = unpack128(preimage[2]);
bool[128] d = unpack128(preimage[3]);
bool[256] lhs = [...a, ...b];
bool[256] rhs = [...c, ...d];
bool[256] r = sha256(lhs, rhs);
field res0 = pack128(r[..128]);
field res1 = pack128(r[128..]);
return [res0, res1];
}

View File

@ -0,0 +1,17 @@
import "./1024bit" as sha256;
// A function that takes 2 bool[256] arrays as inputs
// and returns their sha256 full round output as an array of 256 bool.
def main(bool[256] a, bool[256] b) -> bool[256] {
// Hash is computed on the full 512bit block size
// padding does not fit in the primary block
// add dummy block (single "1" followed by "0" + total length)
bool[256] dummyblock1 = [true, ...[false; 255]];
// Total length of message is 512 bits: 0b1000000000
bool[256] dummyblock2 = [...[false; 246], true, ...[false; 9]];
bool[256] digest = sha256(a, b, dummyblock1, dummyblock2);
return digest;
}

View File

@ -0,0 +1,15 @@
// SHA-256 is specified in FIPS 180-3 and initial values are listed in section 5.3.3
// https://csrc.nist.gov/csrc/media/publications/fips/180/3/archive/2008-10-31/documents/fips180-3_final.pdf
def main() -> bool[256] {
bool[32] h0 = [false, true, true, false, true, false, true, false, false, false, false, false, true, false, false, true, true, true, true, false, false, true, true, false, false, true, true, false, false, true, true, true];
bool[32] h1 = [true, false, true, true, true, false, true, true, false, true, true, false, false, true, true, true, true, false, true, false, true, true, true, false, true, false, false, false, false, true, false, true];
bool[32] h2 = [false, false, true, true, true, true, false, false, false, true, true, false, true, true, true, false, true, true, true, true, false, false, true, true, false, true, true, true, false, false, true, false];
bool[32] h3 = [true, false, true, false, false, true, false, true, false, true, false, false, true, true, true, true, true, true, true, true, false, true, false, true, false, false, true, true, true, false, true, false];
bool[32] h4 = [false, true, false, true, false, false, false, true, false, false, false, false, true, true, true, false, false, true, false, true, false, false, true, false, false, true, true, true, true, true, true, true];
bool[32] h5 = [true, false, false, true, true, false, true, true, false, false, false, false, false, true, false, true, false, true, true, false, true, false, false, false, true, false, false, false, true, true, false, false];
bool[32] h6 = [false, false, false, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true, false, true, true, false, false, true, true, false, true, false, true, false, true, true];
bool[32] h7 = [false, true, false, true, true, false, true, true, true, true, true, false, false, false, false, false, true, true, false, false, true, true, false, true, false, false, false, true, true, false, false, true];
bool[256] IV = [...h0, ...h1, ...h2, ...h3, ...h4, ...h5, ...h6, ...h7];
return IV;
}

View File

@ -0,0 +1,10 @@
#pragma curve bn128
from "EMBED" import sha256round;
// a and b is NOT checked to be 0 or 1
// the return value is checked to be 0 or 1
// IV vector is checked to be of type bool
def main(bool[256] a, bool[256] b, bool[256] IV) -> bool[256] {
return sha256round([...a, ...b], IV);
}

View File

@ -0,0 +1,21 @@
import "./shaRound" as shaRound;
// Initial values, FIPS 180-3, section 5.3.3
// https://csrc.nist.gov/csrc/media/publications/fips/180/3/archive/2008-10-31/documents/fips180-3_final.pdf
const u32[8] IV = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
];
// A function that takes N u32[16] arrays as inputs, concatenates them,
// and returns their sha256 compression as a u32[8].
// Note: no padding is applied
def main<N>(u32[N][16] a) -> u32[8] {
u32[8] mut current = IV;
for u32 i in 0..N {
current = shaRound(a[i], current);
}
return current;
}

View File

@ -0,0 +1,48 @@
import "hashes/sha256/sha256";
import "utils/casts/u8_to_bits";
import "utils/casts/u32_to_bits";
import "utils/casts/u32_from_bits";
// A padding function that takes a bool[L] array as input and pads it to 512-bit blocks
def pad<L, M>(bool[L] m) -> u32[M][16] {
u32 length = L + 64 + 1;
assert(length / 512 + 1 == M);
u32 r = length % 512;
u32 k = 512 - r;
bool[M * 512] result_in_bits = [...m, true, ...[false; k + 32], ...u32_to_bits(L)];
u32[M][16] mut result = [[0; 16]; M];
for u32 i in 0..M {
for u32 j in 0..16 {
u32 start = i * 512 + j * 32;
u32 end = start + 32;
result[i][j] = u32_from_bits(result_in_bits[start..end]);
}
}
return result;
}
// A function that takes a bool[N] array as input, pads it,
// and returns the sha256 output as a u32[8]
def sha256Padded<N>(bool[N] input) -> u32[8] {
u32 block_count = (N + 64 + 1) / 512 + 1;
u32[block_count][16] padded = pad(input);
return sha256(padded);
}
// A function that takes a u8[N] array as input, pads it,
// and returns the sha256 output as a u32[8]
def main<N>(u8[N] input) -> u32[8] {
u32 L = N * 8;
bool[L] mut input_bits = [false; L];
for u32 i in 0..N {
bool[8] bits = u8_to_bits(input[i]);
for u32 j in 0..8 {
input_bits[i * 8 + j] = bits[j];
}
}
return sha256Padded(input_bits);
}

View File

@ -0,0 +1,98 @@
// FIPS 180-3, section 4.2.2
// https://csrc.nist.gov/csrc/media/publications/fips/180/3/archive/2008-10-31/documents/fips180-3_final.pdf
const u32[64] K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
def rotr32<N>(u32 x) -> u32 {
return (x >> N) | (x << (32 - N));
}
def extend(u32[64] w, u32 i) -> u32 {
u32 s0 = rotr32::<7>(w[i-15]) ^ rotr32::<18>(w[i-15]) ^ (w[i-15] >> 3);
u32 s1 = rotr32::<17>(w[i-2]) ^ rotr32::<19>(w[i-2]) ^ (w[i-2] >> 10);
return w[i-16] + s0 + w[i-7] + s1;
}
def temp1(u32 e, u32 f, u32 g, u32 h, u32 k, u32 w) -> u32 {
// ch := (e and f) xor ((not e) and g)
u32 ch = (e & f) ^ ((!e) & g);
// S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)
u32 S1 = rotr32::<6>(e) ^ rotr32::<11>(e) ^ rotr32::<25>(e);
// temp1 := h + S1 + ch + k + w
return h + S1 + ch + k + w;
}
def temp2(u32 a, u32 b, u32 c) -> u32 {
// maj := (a and b) xor (a and c) xor (b and c)
u32 maj = (a & b) ^ (a & c) ^ (b & c);
// S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)
u32 S0 = rotr32::<2>(a) ^ rotr32::<13>(a) ^ rotr32::<22>(a);
// temp2 := S0 + maj
return S0 + maj;
}
// A function that computes one round of the SHA256 compression function given an input and the current value of the hash
// this is used by other components however many times needed
def main(u32[16] input, u32[8] current) -> u32[8] {
u32 mut h0 = current[0];
u32 mut h1 = current[1];
u32 mut h2 = current[2];
u32 mut h3 = current[3];
u32 mut h4 = current[4];
u32 mut h5 = current[5];
u32 mut h6 = current[6];
u32 mut h7 = current[7];
u32[64] mut w = [...input, ...[0u32; 48]];
for u32 i in 16..64 {
w[i] = extend(w, i);
}
u32 mut a = h0;
u32 mut b = h1;
u32 mut c = h2;
u32 mut d = h3;
u32 mut e = h4;
u32 mut f = h5;
u32 mut g = h6;
u32 mut h = h7;
for u32 i in 0..64 {
u32 t1 = temp1(e, f, g, h, K[i], w[i]);
u32 t2 = temp2(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
h5 = h5 + f;
h6 = h6 + g;
h7 = h7 + h;
return [h0, h1, h2, h3, h4, h5, h6, h7];
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[28] {
return keccak::<_, 28>(input, 0x06);
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[32] {
return keccak::<_, 32>(input, 0x06);
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[48] {
return keccak::<_, 48>(input, 0x06);
}

View File

@ -0,0 +1,5 @@
from "hashes/keccak/keccak" import main as keccak;
def main<N>(u8[N] input) -> u8[64] {
return keccak::<_, 64>(input, 0x06);
}

View File

@ -0,0 +1,4 @@
// Concatenate two u32[8] arrays in an order defined by a boolean selector
def main(bool selector, u32[8] lhs, u32[8] rhs) -> u32[16] {
return selector ? [...rhs, ...lhs] : [...lhs, ...rhs];
}

View File

@ -0,0 +1,51 @@
import "hashes/sha256/1024bitPadded" as sha256;
import "ecc/edwardsScalarMult" as scalarMult;
import "ecc/edwardsAdd" as add;
import "utils/pack/bool/nonStrictUnpack256" as unpack256bool;
import "utils/pack/u32/nonStrictUnpack256" as unpack256u;
import "ecc/edwardsOnCurve" as onCurve;
import "ecc/edwardsOrderCheck" as orderCheck;
from "ecc/babyjubjubParams" import BabyJubJubParams;
import "utils/casts/u32_8_to_bool_256";
/// Verifies an EdDSA Signature.
///
/// Checks the correctness of a given EdDSA Signature (R,S) for the provided
/// public key A and message (M0, M1).
/// This python repo provides the tooling for creating valid signatures:
/// https://github.com/Zokrates/pycrypto
///
/// For more information see:
/// https://en.wikipedia.org/wiki/EdDSA
/// https://eprint.iacr.org/2015/677.pdf
///
/// Arguments:
/// R: Curve point. Hidden version of the per-message nonce.
/// S: Field element. Signature to be verified.
/// A: Curve point. Public part of the key used to create S.
/// M0: 256bit array. First 256bits of the message used to create S .
/// M1: 256bit array. Trailing 256bits of the message used to create S .
/// context: Curve parameters used to create S.
///
/// Returns:
/// Return true for S being a valid EdDSA Signature, false otherwise.
def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1, BabyJubJubParams context) -> bool {
field[2] G = [context.Gu, context.Gv];
// Check if R is on curve and if it is not in a small subgroup. A is public input and can be checked offline
assert(onCurve(R, context)); // throws if R is not on curve
assert(orderCheck(R, context));
u32[8] Rx = unpack256u(R[0]);
u32[8] Ax = unpack256u(A[0]);
bool[256] hRAM = u32_8_to_bool_256(sha256(Rx, Ax, M0, M1));
bool[256] sBits = unpack256bool(S);
field[2] lhs = scalarMult(sBits, G, context);
field[2] AhRAM = scalarMult(hRAM, A, context);
field[2] rhs = add(R, AhRAM, context);
bool out = rhs[0] == lhs[0] && rhs[1] == lhs[1];
return out;
}

View File

@ -0,0 +1,56 @@
#pragma curve bw6_761
from "EMBED" import snark_verify_bls12_377 as verify;
struct ProofInner {
field[2] a;
field[2][2] b;
field[2] c;
}
struct Proof<N> {
ProofInner proof;
field[N] inputs;
}
struct VerificationKey<N> {
field[2][2] h;
field[2] g_alpha;
field[2][2] h_beta;
field[2] g_gamma;
field[2][2] h_gamma;
field[N][2] query; // input length + 1
}
def flat<N, F>(field[N][2] input) -> field[F] {
assert(F == N * 2);
field[F] mut out = [0; F];
for u32 i in 0..N {
for u32 j in 0..2 {
out[(i * 2) + j] = input[i][j];
}
}
return out;
}
def main<N, Q>(Proof<N> proof, VerificationKey<Q> vk) -> bool {
assert(Q == N + 1); // query length (Q) should be N + 1
field[8] flat_proof = [
...proof.proof.a,
...flat::<2, 4>(proof.proof.b),
...proof.proof.c
];
u32 two_Q = 2 * Q;
field[16 + (2 * Q)] flat_vk = [
...flat::<2, 4>(vk.h),
...vk.g_alpha,
...flat::<2, 4>(vk.h_beta),
...vk.g_gamma,
...flat::<2, 4>(vk.h_gamma),
...flat::<Q, two_Q>(vk.query)
];
return verify(proof.inputs, flat_proof, flat_vk);
}

View File

@ -0,0 +1,532 @@
from "EMBED" import u64_to_bits, u32_to_bits, u16_to_bits, u8_to_bits, u8_from_bits, u16_from_bits, u32_from_bits, u64_from_bits;
// Cast a boolean array of size 8 to an 8-bit unsigned integer (u8)
def cast(bool[8] input) -> u8 {
return u8_from_bits(input);
}
// Cast a boolean array of size N to an array of 8-bit unsigned integers (u8) of size P
// The following condition must be true `N == 8 * P`, otherwise the cast will fail
def cast<N, P>(bool[N] input) -> u8[P] {
assert(N == 8 * P);
u8[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = u8_from_bits(input[i * 8..(i + 1) * 8]);
}
return r;
}
// Cast a boolean array of size 16 to a 16-bit unsigned integer (u16)
def cast(bool[16] input) -> u16 {
return u16_from_bits(input);
}
// Cast a boolean array of size N to an array of 16-bit unsigned integers (u16) of size P
// The following condition must be true `N == 16 * P`, otherwise the cast will fail
def cast<N, P>(bool[N] input) -> u16[P] {
assert(N == 16 * P);
u16[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = u16_from_bits(input[i * 16..(i + 1) * 16]);
}
return r;
}
// Cast a boolean array of size 32 to a 32-bit unsigned integer (u32)
def cast(bool[32] input) -> u32 {
return u32_from_bits(input);
}
// Cast a boolean array of size N to an array of 32-bit unsigned integers (u32) of size P
// The following condition must be true `N == 32 * P`, otherwise the cast will fail
def cast<N, P>(bool[N] input) -> u32[P] {
assert(N == 32 * P);
u32[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = u32_from_bits(input[i * 32..(i + 1) * 32]);
}
return r;
}
// Cast a boolean array of size 64 to a 64-bit unsigned integer (u64)
def cast(bool[64] input) -> u64 {
return u64_from_bits(input);
}
// Cast a boolean array of size N to an array of 64-bit unsigned integers (u64) of size P
// The following condition must be true `N == 64 * P`, otherwise the cast will fail
def cast<N, P>(bool[N] input) -> u64[P] {
assert(N == 64 * P);
u64[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = u64_from_bits(input[i * 64..(i + 1) * 64]);
}
return r;
}
// Cast an 8-bit unsigned integer (u8) to a boolean array of size 8 (bool[8])
def cast(u8 input) -> bool[8] {
return u8_to_bits(input);
}
// Cast an array of 8-bit unsigned integers (u8) of size N to a boolean array of size P
// The following condition must be true `P == 8 * N`, otherwise the cast will fail
def cast<N, P>(u8[N] input) -> bool[P] {
assert(P == 8 * N);
bool[P] mut r = [false; P];
for u32 i in 0..N {
bool[8] bits = u8_to_bits(input[i]);
for u32 j in 0..8 {
r[i * 8 + j] = bits[j];
}
}
return r;
}
// Cast an 8-bit unsigned integer (u8) to a field element
def cast(u8 input) -> field {
bool[8] bits = u8_to_bits(input);
field mut r = 0;
for u32 i in 0..8 {
u32 exponent = 8 - i - 1;
r = r + (bits[i] ? 2 ** exponent : 0);
}
return r;
}
// Cast an array of 8-bit unsigned integers (u8) to an array of field elements
def cast<N>(u8[N] input) -> field[N] {
field[N] mut r = [0; N];
for u32 i in 0..N {
r[i] = cast(input[i]);
}
return r;
}
// Upcast an 8-bit unsigned integer (u8) to a 16-bit unsigned integer (u16)
def cast(u8 input) -> u16 {
bool[8] bits = u8_to_bits(input);
return u16_from_bits([...[false; 8], ...bits]);
}
// Cast an array of two 8-bit unsigned integers (u8[2]) to a 16-bit unsigned integer (u16)
def cast(u8[2] input) -> u16 {
bool[16] bits = [
...u8_to_bits(input[0]),
...u8_to_bits(input[1])
];
return u16_from_bits(bits);
}
// Cast an array of 8-bit unsigned integers (u8) of size N to an array of 16-bit unsigned integers (u16) of size P
// The following condition must be true `N == 2 * P`, otherwise the cast will fail
def cast<N, P>(u8[N] input) -> u16[P] {
assert(N == 2 * P);
u16[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = cast(input[i * 2..(i + 1) * 2]);
}
return r;
}
// Upcast an 8-bit unsigned integer (u8) to a 32-bit unsigned integer (u32)
def cast(u8 input) -> u32 {
bool[8] bits = u8_to_bits(input);
return u32_from_bits([...[false; 24], ...bits]);
}
// Cast an array of four 8-bit unsigned integers (u8[4]) to a 32-bit unsigned integer (u32)
def cast(u8[4] input) -> u32 {
bool[32] bits = [
...u8_to_bits(input[0]),
...u8_to_bits(input[1]),
...u8_to_bits(input[2]),
...u8_to_bits(input[3])
];
return u32_from_bits(bits);
}
// Cast an array of 8-bit unsigned integers (u8) of size N to an array of 32-bit unsigned integers (u32) of size P
// The following condition must be true `N == 4 * P`, otherwise the cast will fail
def cast<N, P>(u8[N] input) -> u32[P] {
assert(N == 4 * P);
u32[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = cast(input[i * 4..(i + 1) * 4]);
}
return r;
}
// Upcast an 8-bit unsigned integer (u8) to a 64-bit unsigned integer (u64)
def cast(u8 input) -> u64 {
bool[8] bits = u8_to_bits(input);
return u64_from_bits([...[false; 56], ...bits]);
}
// Cast an array of eight 8-bit unsigned integers (u8[8]) to a 64-bit unsigned integer (u64)
def cast(u8[8] input) -> u64 {
bool[64] bits = [
...u8_to_bits(input[0]),
...u8_to_bits(input[1]),
...u8_to_bits(input[2]),
...u8_to_bits(input[3]),
...u8_to_bits(input[4]),
...u8_to_bits(input[5]),
...u8_to_bits(input[6]),
...u8_to_bits(input[7])
];
return u64_from_bits(bits);
}
// Cast an array of 8-bit unsigned integers (u8) of size N to an array of 64-bit unsigned integers (u64) of size P
// The following condition must be true `N == 8 * P`, otherwise the cast will fail
def cast<N, P>(u8[N] input) -> u64[P] {
assert(N == 8 * P);
u64[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = cast(input[i * 8..(i + 1) * 8]);
}
return r;
}
// Cast a 16-bit unsigned integer (u16) to a boolean array of size 16 (bool[16])
def cast(u16 input) -> bool[16] {
return u16_to_bits(input);
}
// Cast an array of 16-bit unsigned integers (u16) of size N to a boolean array of size P
// The following condition must be true `P == 16 * N`, otherwise the cast will fail
def cast<N, P>(u16[N] input) -> bool[P] {
assert(P == 16 * N);
bool[P] mut r = [false; P];
for u32 i in 0..N {
bool[16] bits = u16_to_bits(input[i]);
for u32 j in 0..16 {
r[i * 16 + j] = bits[j];
}
}
return r;
}
// Cast a 16-bit unsigned integer (u16) to a field element
def cast(u16 input) -> field {
bool[16] bits = u16_to_bits(input);
field mut r = 0;
for u32 i in 0..16 {
u32 exponent = 16 - i - 1;
r = r + (bits[i] ? 2 ** exponent : 0);
}
return r;
}
// Cast an array of 16-bit unsigned integers (u16) to an array of field elements
def cast<N>(u16[N] input) -> field[N] {
field[N] mut r = [0; N];
for u32 i in 0..N {
r[i] = cast(input[i]);
}
return r;
}
// Cast a 16-bit unsigned integer (u16) to an array of two 8-bit unsigned integers (u8[2])
def cast(u16 input) -> u8[2] {
bool[16] bits = u16_to_bits(input);
return [
u8_from_bits(bits[0..8]),
u8_from_bits(bits[8..16])
];
}
// Cast an array of 16-bit unsigned integers (u16) of size N to an array of 8-bit unsigned integers of size P
// The following condition must be true `P == 2 * N`, otherwise the cast will fail
def cast<N, P>(u16[N] input) -> u8[P] {
assert(P == 2 * N);
u8[P] mut r = [0; P];
for u32 i in 0..N {
u8[2] t = cast(input[i]);
r[i * 2] = t[0];
r[i * 2 + 1] = t[1];
}
return r;
}
// Upcast a 16-bit unsigned integer (u16) to a 32-bit unsigned integer (u32)
def cast(u16 input) -> u32 {
bool[16] bits = u16_to_bits(input);
return u32_from_bits([...[false; 16], ...bits]);
}
// Cast an array of two 16-bit unsigned integers (u16[2]) to a 32-bit unsigned integer (u32)
def cast(u16[2] input) -> u32 {
bool[32] bits = [
...u16_to_bits(input[0]),
...u16_to_bits(input[1])
];
return u32_from_bits(bits);
}
// Cast an array of 16-bit unsigned integers (u16) of size N to an array of 32-bit unsigned integers (u32) of size P
// The following condition must be true `N == 2 * P`, otherwise the cast will fail
def cast<N, P>(u16[N] input) -> u32[P] {
assert(N == 2 * P);
u32[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = cast(input[i * 2..(i + 1) * 2]);
}
return r;
}
// Upcast a 16-bit unsigned integer (u16) to a 64-bit unsigned integer (u64)
def cast(u16 input) -> u64 {
bool[16] bits = u16_to_bits(input);
return u64_from_bits([...[false; 48], ...bits]);
}
// Cast an array of four 16-bit unsigned integers (u16[4]) to a 64-bit unsigned integer (u64)
def cast(u16[4] input) -> u64 {
bool[64] bits = [
...u16_to_bits(input[0]),
...u16_to_bits(input[1]),
...u16_to_bits(input[2]),
...u16_to_bits(input[3])
];
return u64_from_bits(bits);
}
// Cast an array of 16-bit unsigned integers (u16) of size N to an array of 64-bit unsigned integers (u64) of size P
// The following condition must be true `N == 4 * P`, otherwise the cast will fail
def cast<N, P>(u16[N] input) -> u64[P] {
assert(N == 4 * P);
u64[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = cast(input[i * 4..(i + 1) * 4]);
}
return r;
}
// Cast a 32-bit unsigned integer (u32) to a boolean array of size 32 (bool[32])
def cast(u32 input) -> bool[32] {
return u32_to_bits(input);
}
// Cast an array of 32-bit unsigned integers (u32) of size N to a boolean array of size P
// The following condition must be true `P == 32 * N`, otherwise the cast will fail
def cast<N, P>(u32[N] input) -> bool[P] {
assert(P == 32 * N);
bool[P] mut r = [false; P];
for u32 i in 0..N {
bool[32] bits = u32_to_bits(input[i]);
for u32 j in 0..32 {
r[i * 32 + j] = bits[j];
}
}
return r;
}
// Cast a 32-bit unsigned integer (u32) to a field element
def cast(u32 input) -> field {
bool[32] bits = u32_to_bits(input);
field mut r = 0;
for u32 i in 0..32 {
u32 exponent = 32 - i - 1;
r = r + (bits[i] ? 2 ** exponent : 0);
}
return r;
}
// Cast an array of 32-bit unsigned integers (u32) to an array of field elements
def cast<N>(u32[N] input) -> field[N] {
field[N] mut r = [0; N];
for u32 i in 0..N {
r[i] = cast(input[i]);
}
return r;
}
// Cast a 32-bit unsigned integer (u32) to an array of four 8-bit unsigned integers (u8[4])
def cast(u32 input) -> u8[4] {
bool[32] bits = u32_to_bits(input);
return [
u8_from_bits(bits[0..8]),
u8_from_bits(bits[8..16]),
u8_from_bits(bits[16..24]),
u8_from_bits(bits[24..32])
];
}
// Cast an array of 32-bit unsigned integers (u32) of size N to an array of 8-bit unsigned integers of size P
// The following condition must be true `P == 4 * N`, otherwise the cast will fail
def cast<N, P>(u32[N] input) -> u8[P] {
assert(P == 4 * N);
u8[P] mut r = [0; P];
for u32 i in 0..N {
u8[4] t = cast(input[i]);
for u32 j in 0..4 {
r[i * 4 + j] = t[j];
}
}
return r;
}
// Cast a 32-bit unsigned integer (u32) to an array of two 16-bit unsigned integers (u16[2])
def cast(u32 input) -> u16[2] {
bool[32] bits = u32_to_bits(input);
return [
u16_from_bits(bits[0..16]),
u16_from_bits(bits[16..32])
];
}
// Cast an array of 32-bit unsigned integers (u32) of size N to an array of 16-bit unsigned integers of size P
// The following condition must be true `P == 2 * N`, otherwise the cast will fail
def cast<N, P>(u32[N] input) -> u16[P] {
assert(P == 2 * N);
u16[P] mut r = [0; P];
for u32 i in 0..N {
u16[2] t = cast(input[i]);
r[i * 2] = t[0];
r[i * 2 + 1] = t[1];
}
return r;
}
// Upcast a 32-bit unsigned integer (u32) to a 64-bit unsigned integer (u64)
def cast(u32 input) -> u64 {
bool[32] bits = u32_to_bits(input);
return u64_from_bits([...[false; 32], ...bits]);
}
// Cast an array of two 32-bit unsigned integers (u32[2]) to a 64-bit unsigned integer (u64)
def cast(u32[2] input) -> u64 {
bool[64] bits = [
...u32_to_bits(input[0]),
...u32_to_bits(input[1])
];
return u64_from_bits(bits);
}
// Cast an array of 32-bit unsigned integers (u32) of size N to an array of 64-bit unsigned integers (u64) of size P
// The following condition must be true `N == 2 * P`, otherwise the cast will fail
def cast<N, P>(u32[N] input) -> u64[P] {
assert(N == 2 * P);
u64[P] mut r = [0; P];
for u32 i in 0..P {
r[i] = cast(input[i * 2..(i + 1) * 2]);
}
return r;
}
// Cast a 64-bit unsigned integer (u64) to a boolean array of size 64 (bool[64])
def cast(u64 input) -> bool[64] {
return u64_to_bits(input);
}
// Cast an array of 64-bit unsigned integers (u64) of size N to a boolean array of size P
// The following condition must be true `P == 64 * N`, otherwise the cast will fail
def cast<N, P>(u64[N] input) -> bool[P] {
assert(P == 64 * N);
bool[P] mut r = [false; P];
for u32 i in 0..N {
bool[64] bits = u64_to_bits(input[i]);
for u32 j in 0..64 {
r[i * 64 + j] = bits[j];
}
}
return r;
}
// Cast 64-bit unsigned integer (u64) to a field element
def cast(u64 input) -> field {
bool[64] bits = u64_to_bits(input);
field mut r = 0;
for u32 i in 0..64 {
u32 exponent = 64 - i - 1;
r = r + (bits[i] ? 2 ** exponent : 0);
}
return r;
}
// Cast an array of 64-bit unsigned integers (u64) to an array of field elements
def cast<N>(u64[N] input) -> field[N] {
field[N] mut r = [0; N];
for u32 i in 0..N {
r[i] = cast(input[i]);
}
return r;
}
// Cast a 64-bit unsigned integer (u64) to an array of 8 8-bit unsigned integers (u8[8])
def cast(u64 input) -> u8[8] {
bool[64] bits = u64_to_bits(input);
return [
u8_from_bits(bits[0..8]),
u8_from_bits(bits[8..16]),
u8_from_bits(bits[16..24]),
u8_from_bits(bits[24..32]),
u8_from_bits(bits[32..40]),
u8_from_bits(bits[40..48]),
u8_from_bits(bits[48..56]),
u8_from_bits(bits[56..64])
];
}
// Cast an array of 64-bit unsigned integers (u64) of size N to an array of 8-bit unsigned integers of size P
// The following condition must be true `P == 8 * N`, otherwise the cast will fail
def cast<N, P>(u64[N] input) -> u8[P] {
assert(P == 8 * N);
u8[P] mut r = [0; P];
for u32 i in 0..N {
u8[8] t = cast(input[i]);
for u32 j in 0..8 {
r[i * 8 + j] = t[j];
}
}
return r;
}
// Cast a 64-bit unsigned integer (u64) to an array of 4 16-bit unsigned integers (u16[4])
def cast(u64 input) -> u16[4] {
bool[64] bits = u64_to_bits(input);
return [
u16_from_bits(bits[0..16]),
u16_from_bits(bits[16..32]),
u16_from_bits(bits[32..48]),
u16_from_bits(bits[48..64])
];
}
// Cast an array of 64-bit unsigned integers (u64) of size N to an array of 16-bit unsigned integers of size P
// The following condition must be true `P == 4 * N`, otherwise the cast will fail
def cast<N, P>(u64[N] input) -> u16[P] {
assert(P == 4 * N);
u16[P] mut r = [0; P];
for u32 i in 0..N {
u16[4] t = cast(input[i]);
for u32 j in 0..4 {
r[i * 4 + j] = t[j];
}
}
return r;
}
// Cast a 64-bit unsigned integer (u64) to an array of 2 32-bit unsigned integers (u32[2])
def cast(u64 input) -> u32[2] {
bool[64] bits = u64_to_bits(input);
return [
u32_from_bits(bits[0..32]),
u32_from_bits(bits[32..64])
];
}
// Cast an array of 64-bit unsigned integers (u64) of size N to an array of 32-bit unsigned integers of size P
// The following condition must be true `P == 2 * N`, otherwise the cast will fail
def cast<N, P>(u64[N] input) -> u32[P] {
assert(P == 2 * N);
u32[P] mut r = [0; P];
for u32 i in 0..N {
u32[2] t = cast(input[i]);
r[i * 2] = t[0];
r[i * 2 + 1] = t[1];
}
return r;
}

View File

@ -0,0 +1,6 @@
import "./bool_array_to_u32_array" as bool_to_u32;
def main(bool[128] bits) -> u32[4] {
u32[4] res = bool_to_u32(bits);
return res;
}

View File

@ -0,0 +1,6 @@
import "./bool_array_to_u32_array" as bool_to_u32;
def main(bool[256] bits) -> u32[8] {
u32[8] res = bool_to_u32(bits);
return res;
}

View File

@ -0,0 +1,15 @@
from "EMBED" import u32_from_bits;
// convert an array of bool to an array of u32
// the sizes must match (one u32 for 32 bool) otherwise an error will happen
def main<N, P>(bool[N] bits) -> u32[P] {
assert(N == 32 * P);
u32[P] mut res = [0; P];
for u32 i in 0..P {
res[i] = u32_from_bits(bits[32 * i..32 * (i + 1)]);
}
return res;
}

View File

@ -0,0 +1,8 @@
from "field" import FIELD_SIZE_IN_BITS;
import "utils/pack/bool/unpack";
import "utils/casts/u16_from_bits";
def main(field input) -> u16 {
bool[FIELD_SIZE_IN_BITS] bits = unpack(input);
return u16_from_bits(bits[FIELD_SIZE_IN_BITS-16..]);
}

View File

@ -0,0 +1,8 @@
from "field" import FIELD_SIZE_IN_BITS;
import "utils/pack/bool/unpack";
import "utils/casts/u32_from_bits";
def main(field input) -> u32 {
bool[FIELD_SIZE_IN_BITS] bits = unpack(input);
return u32_from_bits(bits[FIELD_SIZE_IN_BITS-32..]);
}

View File

@ -0,0 +1,8 @@
from "field" import FIELD_SIZE_IN_BITS;
import "utils/pack/bool/unpack";
import "utils/casts/u64_from_bits";
def main(field input) -> u64 {
bool[FIELD_SIZE_IN_BITS] bits = unpack(input);
return u64_from_bits(bits[FIELD_SIZE_IN_BITS-64..]);
}

View File

@ -0,0 +1,8 @@
from "field" import FIELD_SIZE_IN_BITS;
import "utils/pack/bool/unpack";
import "utils/casts/u8_from_bits";
def main(field input) -> u8 {
bool[FIELD_SIZE_IN_BITS] bits = unpack(input);
return u8_from_bits(bits[FIELD_SIZE_IN_BITS-8..]);
}

View File

@ -0,0 +1,5 @@
from "EMBED" import u16_from_bits;
def main(bool[16] a) -> u16 {
return u16_from_bits(a);
}

View File

@ -0,0 +1,5 @@
from "EMBED" import u16_to_bits;
def main(u16 a) -> bool[16] {
return u16_to_bits(a);
}

View File

@ -0,0 +1,11 @@
from "EMBED" import u16_to_bits;
def main(u16 i) -> field {
bool[16] bits = u16_to_bits(i);
field mut res = 0;
for u32 j in 0..16 {
u32 exponent = 16 - j - 1;
res = res + (bits[j] ? 2 ** exponent : 0);
}
return res;
}

View File

@ -0,0 +1,6 @@
import "./u32_array_to_bool_array" as to_bool_array;
def main(u32[4] input) -> bool[128] {
bool[128] res = to_bool_array(input);
return res;
}

View File

@ -0,0 +1,6 @@
import "./u32_array_to_bool_array" as to_bool_array;
def main(u32[8] input) -> bool[256] {
bool[256] res = to_bool_array(input);
return res;
}

View File

@ -0,0 +1,16 @@
from "EMBED" import u32_to_bits;
def main<N, P>(u32[N] input) -> bool[P] {
assert(P == 32 * N);
bool[P] mut res = [false; P];
for u32 i in 0..N {
bool[32] bits = u32_to_bits(input[i]);
for u32 j in 0..32 {
res[i * 32 + j] = bits[j];
}
}
return res;
}

View File

@ -0,0 +1,5 @@
from "EMBED" import u32_from_bits;
def main(bool[32] a) -> u32 {
return u32_from_bits(a);
}

View File

@ -0,0 +1,5 @@
from "EMBED" import u32_to_bits;
def main(u32 a) -> bool[32] {
return u32_to_bits(a);
}

Some files were not shown because too many files have changed in this diff Show More