Skip to content

Instantly share code, notes, and snippets.

@tupui
Last active December 16, 2025 10:59
Show Gist options
  • Select an option

  • Save tupui/5975eb588ff18afe5a652fe453eba345 to your computer and use it in GitHub Desktop.

Select an option

Save tupui/5975eb588ff18afe5a652fe453eba345 to your computer and use it in GitHub Desktop.
Pedersen commitment for anonymous voting in Stellar Smart Contract
// Copyright (c) 2025, Pamphile Roy
// SPDX-License-Identifier: MIT
use soroban_sdk::crypto::bls12_381::Fr;
use soroban_sdk::{Bytes, Env, U256};
let env = Env::default();
let bls12_381 = env.crypto().bls12_381();
// generators
let vote_generator = Bytes::from_slice(&env, b"VOTE_GENERATOR");
let vote_dst = Bytes::from_slice(&env, b"VOTE_COMMITMENT");
let seed_generator = Bytes::from_slice(&env, b"SEED_GENERATOR");
let seed_dst = Bytes::from_slice(&env, b"VOTE_SEED");
let vote_generator_point = bls12_381.hash_to_g1(&vote_generator, &vote_dst);
let seed_generator_point = bls12_381.hash_to_g1(&seed_generator, &seed_dst);
// votes
let vote_a = Fr::from_u256(U256::from_u128(&env, 1_u128));
let seed_a = Fr::from_u256(U256::from_u128(&env, 60_u128));
let vote_b = Fr::from_u256(U256::from_u128(&env, 2_u128));
let seed_b = Fr::from_u256(U256::from_u128(&env, 30_u128));
// casting votes, on-chain store commitments
// C = g^v * h^r (in additive notation: g*v + h*r)
let vote_point = bls12_381.g1_mul(&vote_generator_point, &vote_a);
let seed_point = bls12_381.g1_mul(&seed_generator_point, &seed_a);
let commitment_a = bls12_381.g1_add(&vote_point, &seed_point);
let vote_point = bls12_381.g1_mul(&vote_generator_point, &vote_b);
let seed_point = bls12_381.g1_mul(&seed_generator_point, &seed_b);
let commitment_b = bls12_381.g1_add(&vote_point, &seed_point);
let tally_commitment = bls12_381.g1_add(&commitment_a, &commitment_b);
// collect votes info and prove tally by sending votes and seeds on-chain
let tally_vote_point = bls12_381.g1_mul(&vote_generator_point, &(vote_a + vote_b));
let tally_seed_point = bls12_381.g1_mul(&seed_generator_point, &(seed_a + seed_b));
let commitment_check = bls12_381.g1_add(&tally_vote_point, &tally_seed_point);
assert_eq!(commitment_check, tally_commitment);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment