You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.7 KiB

use super::group::{GroupElement, VartimeMultiscalarMul, GROUP_BASEPOINT_COMPRESSED};
use super::scalar::Scalar;
use digest::{ExtendableOutput, Input, XofReader};
use sha3::Shake256;
#[derive(Debug)]
pub struct MultiCommitGens {
pub n: usize,
pub G: Vec<GroupElement>,
pub h: GroupElement,
}
impl MultiCommitGens {
pub fn new(n: usize, label: &[u8]) -> Self {
let mut shake = Shake256::default();
shake.input(label);
shake.input(GROUP_BASEPOINT_COMPRESSED.as_bytes());
let mut reader = shake.xof_result();
let mut gens: Vec<GroupElement> = Vec::new();
let mut uniform_bytes = [0u8; 64];
for _ in 0..n + 1 {
reader.read(&mut uniform_bytes);
gens.push(GroupElement::from_uniform_bytes(&uniform_bytes));
}
MultiCommitGens {
n,
G: gens[0..n].to_vec(),
h: gens[n],
}
}
pub fn clone(&self) -> MultiCommitGens {
MultiCommitGens {
n: self.n,
h: self.h,
G: self.G.clone(),
}
}
pub fn split_at_mut(&mut self, mid: usize) -> (MultiCommitGens, MultiCommitGens) {
let (G1, G2) = self.G.split_at_mut(mid);
(
MultiCommitGens {
n: G1.len(),
G: G1.to_vec(),
h: self.h,
},
MultiCommitGens {
n: G2.len(),
G: G2.to_vec(),
h: self.h,
},
)
}
}
pub trait Commitments {
fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement;
}
impl Commitments for Scalar {
fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
assert!(gens_n.n == 1);
GroupElement::vartime_multiscalar_mul(&[*self, *blind], &[gens_n.G[0], gens_n.h])
}
}
impl Commitments for Vec<Scalar> {
fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
assert!(gens_n.n == self.len());
GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + blind * &gens_n.h
}
}
impl Commitments for [Scalar] {
fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
assert_eq!(gens_n.n, self.len());
GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + blind * &gens_n.h
}
}
impl Commitments for Vec<bool> {
fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
assert!(gens_n.n == self.len());
let mut comm = blind * &gens_n.h;
for i in 0..self.len() {
if self[i] {
comm = comm + gens_n.G[i];
}
}
comm
}
}
impl Commitments for [bool] {
fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
assert!(gens_n.n == self.len());
let mut comm = blind * &gens_n.h;
for i in 0..self.len() {
if self[i] {
comm = comm + gens_n.G[i];
}
}
comm
}
}