indcpacom

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

indcpacom

IND-CPA commitment scheme constructed from encryption.

Overview

This package implements a commitment scheme based on any IND-CPA (indistinguishability under chosen-plaintext attack) secure encryption scheme. The construction is:

  • Commit(m) = Encrypt(m, r) using randomness r
  • Commitment = the resulting ciphertext
  • Witness = the encryption nonce/randomness r

Security Properties

  • Hiding: Inherited from the semantic security of the encryption scheme
  • Binding: Inherited from the correctness of decryption
  • Re-randomizable: Commitments can be re-randomized to produce new commitments to the same message

Usage

import (
    "crypto/rand"

    "github.com/bronlabs/bron-crypto/pkg/commitments/indcpacom"
    "github.com/bronlabs/bron-crypto/pkg/encryption/paillier"
)

// Setup: create encryption scheme and generate keys
paillierScheme := paillier.NewScheme()
kg, _ := paillierScheme.Keygen()
_, pk, _ := kg.Generate(rand.Reader)

// Create commitment scheme
key, _ := indcpacom.NewKey(pk)
scheme, _ := indcpacom.NewScheme(paillierScheme, key)

// Commit to a message
plaintext, _ := pk.PlaintextSpace().Sample(nil, nil, rand.Reader)
message, _ := indcpacom.NewMessage(plaintext)

committer, _ := scheme.Committer()
commitment, witness, _ := committer.Commit(message, rand.Reader)

// Verify the commitment
verifier, _ := scheme.Verifier()
err := verifier.Verify(commitment, message, witness)
// err == nil if verification succeeds

// Re-randomize a commitment
newCommitment, rerandWitness, _ := commitment.ReRandomise(key, rand.Reader)

// Verify re-randomized commitment using combined witness
combinedWitness := witness.Op(rerandWitness)
err = verifier.Verify(newCommitment, message, combinedWitness)

Deterministic Commitments

For protocols requiring deterministic commitment creation:

// Create witness from a known nonce
nonce, _ := pk.NonceSpace().Sample(rand.Reader)
witness, _ := indcpacom.NewWitness(nonce)

// Commit deterministically
commitment, _ := committer.CommitWithWitness(message, witness)

Witness Combination

When a commitment is re-randomized, verifying the new commitment requires combining the original witness with the re-randomization witness using the Op method:

// Original commitment with witness
commitment, witness, _ := committer.Commit(message, rand.Reader)

// Re-randomize
newCommitment, rerandWitness, _ := commitment.ReRandomise(key, rand.Reader)

// Combine witnesses to verify re-randomized commitment
combinedWitness := witness.Op(rerandWitness)
verifier.Verify(newCommitment, message, combinedWitness)

// Multiple re-randomizations chain the witness combinations
commitment2, rerandWitness2, _ := newCommitment.ReRandomise(key, rand.Reader)
combinedWitness2 := combinedWitness.Op(rerandWitness2)
verifier.Verify(commitment2, message, combinedWitness2)

Documentation

Overview

Package indcpacom implements a commitment scheme based on IND-CPA secure encryption. Any IND-CPA (indistinguishability under chosen-plaintext attack) secure encryption scheme can be transformed into a commitment scheme where:

  • Commit(m) = Encrypt(m, r) using randomness r as the witness
  • The commitment is the ciphertext
  • The witness is the encryption nonce/randomness

This construction inherits the hiding property from the semantic security of the encryption scheme and the binding property from the correctness of decryption.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrIsNil is returned when a required value is nil.
	ErrIsNil = errs.New("value is nil")
	// ErrVerificationFailed is returned when commitment verification fails.
	ErrVerificationFailed = errs.New("commitment verification failed")
	// ErrInvalidType is returned when a type assertion fails.
	ErrInvalidType = errs.New("invalid type")
)

Errors returned by the indcpacom package.

Functions

This section is empty.

Types

type Commitment

type Commitment[C encryption.ReRandomisableCiphertext[C, N, PK], N interface {
	encryption.Nonce
	algebra.Operand[N]
}, PK encryption.PublicKey[PK]] struct {
	// contains filtered or unexported fields
}

Commitment represents an IND-CPA commitment, which is the ciphertext resulting from encrypting the committed message.

func (*Commitment[C, N, PK]) Equal

func (c *Commitment[C, N, PK]) Equal(other *Commitment[C, N, PK]) bool

Equal returns true if two commitments are equal (i.e., contain equal ciphertexts).

func (*Commitment[C, N, PK]) ReRandomise

func (c *Commitment[C, N, PK]) ReRandomise(k *Key[PK], prng io.Reader) (*Commitment[C, N, PK], *Witness[N], error)

ReRandomise re-randomises the commitment using fresh randomness from prng. This produces a new commitment to the same message with different randomness, along with the witness used for re-randomisation. Returns an error if the key or prng is nil.

func (*Commitment[C, N, PK]) ReRandomiseWithWitness

func (c *Commitment[C, N, PK]) ReRandomiseWithWitness(k *Key[PK], w *Witness[N]) (*Commitment[C, N, PK], error)

ReRandomiseWithWitness re-randomises the commitment using the provided witness. This produces a new commitment to the same message with different randomness. The same witness will always produce the same re-randomised commitment. Returns an error if the key or witness is nil.

func (*Commitment[C, N, PK]) Value

func (c *Commitment[C, N, PK]) Value() C

Value returns the underlying ciphertext of the commitment.

type Committer

type Committer[
	N interface {
		encryption.Nonce
		algebra.Operand[N]
	}, P encryption.Plaintext, CX encryption.ReRandomisableCiphertext[CX, N, PK],
	PK encryption.PublicKey[PK],
] struct {
	// contains filtered or unexported fields
}

Committer creates IND-CPA commitments by encrypting messages.

func (*Committer[N, P, CX, PK]) Commit

func (c *Committer[N, P, CX, PK]) Commit(
	message *Message[P],
	prng io.Reader,
) (*Commitment[CX, N, PK], *Witness[N], error)

Commit creates a commitment to the given message using fresh randomness from prng. Returns the commitment and the witness (nonce) needed to open it. Returns an error if the message or prng is nil.

func (*Committer[N, P, CX, PK]) CommitWithWitness

func (c *Committer[N, P, CX, PK]) CommitWithWitness(
	message *Message[P],
	witness *Witness[N],
) (*Commitment[CX, N, PK], error)

CommitWithWitness creates a commitment to the given message using the provided witness. This allows for deterministic commitment creation when the same witness is used. Returns an error if the message or witness is nil.

type CommitterOption

type CommitterOption[
	N interface {
		encryption.Nonce
		algebra.Operand[N]
	}, P encryption.Plaintext, CX encryption.ReRandomisableCiphertext[CX, N, PK],
	PK encryption.PublicKey[PK],
] = func(*Committer[N, P, CX, PK]) error

CommitterOption is a functional option for configuring a Committer.

type Key

type Key[PK encryption.PublicKey[PK]] struct {
	// contains filtered or unexported fields
}

Key wraps the public key used for the IND-CPA commitment scheme.

func NewKey

func NewKey[PK encryption.PublicKey[PK]](v PK) (*Key[PK], error)

NewKey creates a new Key from a public key. Returns an error if the provided public key is nil.

func (*Key[PK]) Value

func (k *Key[PK]) Value() PK

Value returns the underlying public key.

type Message

type Message[M encryption.Plaintext] struct {
	// contains filtered or unexported fields
}

Message wraps a plaintext value to be committed.

func NewMessage

func NewMessage[M encryption.Plaintext](v M) (*Message[M], error)

NewMessage creates a new Message from a plaintext value. Returns an error if the provided plaintext is nil.

func (*Message[M]) Value

func (m *Message[M]) Value() M

Value returns the underlying plaintext.

type Scheme

type Scheme[
	SK encryption.PrivateKey[SK], PK encryption.PublicKey[PK], M encryption.Plaintext, C encryption.ReRandomisableCiphertext[C, N, PK], N interface {
		encryption.Nonce
		algebra.Operand[N]
	}, KG encryption.KeyGenerator[SK, PK], ENC encryption.Encrypter[PK, M, C, N], DEC encryption.Decrypter[M, C],
] struct {
	// contains filtered or unexported fields
}

Scheme represents an IND-CPA commitment scheme constructed from an encryption scheme. It wraps an encryption scheme and a public key, using encryption as the commitment mechanism.

func NewScheme

func NewScheme[
	SK encryption.PrivateKey[SK], PK encryption.PublicKey[PK], M encryption.Plaintext,
	C encryption.ReRandomisableCiphertext[C, N, PK], N interface {
		encryption.Nonce
		algebra.Operand[N]
	}, KG encryption.KeyGenerator[SK, PK], ENC encryption.Encrypter[PK, M, C, N], DEC encryption.Decrypter[M, C],
](
	encScheme encryption.Scheme[SK, PK, M, C, N, KG, ENC, DEC],
	key *Key[PK],
) (*Scheme[SK, PK, M, C, N, KG, ENC, DEC], error)

NewScheme creates a new IND-CPA commitment scheme from an encryption scheme and public key. Returns an error if either argument is nil.

func (*Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Committer

func (s *Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Committer(opts ...CommitterOption[N, M, C, PK]) (*Committer[N, M, C, PK], error)

Committer creates a new Committer instance for creating commitments. The underlying encryption scheme must implement LinearlyRandomisedEncrypter.

func (*Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Key

func (s *Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Key() *Key[PK]

Key returns the public key used by this commitment scheme.

func (*Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Name

func (s *Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Name() commitments.Name

Name returns the name of the commitment scheme, which includes the underlying encryption scheme name.

func (*Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Verifier

func (s *Scheme[SK, PK, M, C, N, KG, ENC, DEC]) Verifier(opts ...VerifierOption[N, M, C, PK]) (*Verifier[N, M, C, PK], error)

Verifier creates a new Verifier instance for verifying commitments.

type Verifier

type Verifier[
	N interface {
		encryption.Nonce
		algebra.Operand[N]
	}, P encryption.Plaintext, CX encryption.ReRandomisableCiphertext[CX, N, PK],
	PK encryption.PublicKey[PK],
] struct {
	// contains filtered or unexported fields
}

Verifier verifies IND-CPA commitments by re-computing the commitment from the message and witness and comparing it to the provided commitment.

func (*Verifier[N, P, CX, PK]) Verify

func (v *Verifier[N, P, CX, PK]) Verify(
	commitment *Commitment[CX, N, PK],
	message *Message[P],
	witness *Witness[N],
) error

Verify checks that the commitment is valid for the given message and witness. It re-computes the commitment from the message and witness and compares it to the provided commitment. Returns nil if verification succeeds, or an error if verification fails.

type VerifierOption

type VerifierOption[
	N interface {
		encryption.Nonce
		algebra.Operand[N]
	}, P encryption.Plaintext, CX encryption.ReRandomisableCiphertext[CX, N, PK],
	PK encryption.PublicKey[PK],
] = func(*Verifier[N, P, CX, PK]) error

VerifierOption is a functional option for configuring a Verifier.

type Witness

type Witness[N interface {
	encryption.Nonce
	algebra.Operand[N]
}] struct {
	// contains filtered or unexported fields
}

Witness wraps the nonce/randomness used in the commitment. The witness is required to open (verify) a commitment.

func NewWitness

func NewWitness[N interface {
	encryption.Nonce
	algebra.Operand[N]
}](v N) (*Witness[N], error)

NewWitness creates a new Witness from a nonce value. Returns an error if the provided nonce is nil.

func (*Witness[N]) Op

func (w *Witness[N]) Op(other *Witness[N]) *Witness[N]

Op combines two witnesses by applying the underlying nonce operation. This is used to compute the combined witness needed to verify a re-randomised commitment: if C' = ReRandomise(C, r'), then Verify(C', m, w.Op(w')) succeeds where w is the original witness and w' is the re-randomization witness. Panics if other is nil.

func (*Witness[N]) Value

func (w *Witness[N]) Value() N

Value returns the underlying nonce.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL